summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llrender/llglslshader.cpp20
-rw-r--r--indra/llrender/llglslshader.h9
-rw-r--r--indra/llrender/llvertexbuffer.cpp62
-rw-r--r--indra/llrender/llvertexbuffer.h1
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl112
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/moonF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/starsF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/waterV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/moonF.glsl51
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/moonV.glsl (renamed from indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl)18
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/starsF.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl)30
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/starsV.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl)38
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/moonF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl6
-rw-r--r--indra/newview/llagentcamera.cpp7
-rw-r--r--indra/newview/llappviewer.cpp2
-rw-r--r--indra/newview/lldrawpoolsky.cpp21
-rw-r--r--indra/newview/lldrawpoolwater.cpp229
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp16
-rw-r--r--indra/newview/llviewershadermgr.cpp40
-rw-r--r--indra/newview/llviewershadermgr.h2
-rw-r--r--indra/newview/llviewerstats.cpp106
24 files changed, 473 insertions, 325 deletions
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index d634945632..e3b29dc812 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -61,6 +61,21 @@ U32 LLGLSLShader::sTotalDrawCalls = 0;
LLGLSLShader gUIProgram;
LLGLSLShader gSolidColorProgram;
+// NOTE: Keep gShaderConsts* and LLGLSLShader::ShaderConsts_e in sync!
+const std::string gShaderConstsKey[ LLGLSLShader::NUM_SHADER_CONSTS ] =
+{
+ "LL_SHADER_CONST_CLOUD_MOON_DEPTH"
+ , "LL_SHADER_CONST_STAR_DEPTH"
+};
+
+// NOTE: Keep gShaderConsts* and LLGLSLShader::ShaderConsts_e in sync!
+const std::string gShaderConstsVal[ LLGLSLShader::NUM_SHADER_CONSTS ] =
+{
+ "0.99998" // SHADER_CONST_CLOUD_MOON_DEPTH // SL-14113
+ , "0.99999" // SHADER_CONST_STAR_DEPTH // SL-14113
+};
+
+
BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
{
return v1 != v2;
@@ -776,6 +791,11 @@ void LLGLSLShader::addPermutation(std::string name, std::string value)
mDefines[name] = value;
}
+void LLGLSLShader::addConstant( const LLGLSLShader::eShaderConsts shader_const )
+{
+ addPermutation( gShaderConstsKey[ shader_const ], gShaderConstsVal[ shader_const ] );
+}
+
void LLGLSLShader::removePermutation(std::string name)
{
mDefines[name].erase();
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 67a9fca53a..23db1a8549 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -135,6 +135,13 @@ public:
class LLGLSLShader
{
public:
+ // NOTE: Keep gShaderConsts and LLGLSLShader::ShaderConsts_e in sync!
+ enum eShaderConsts
+ {
+ SHADER_CONST_CLOUD_MOON_DEPTH
+ , SHADER_CONST_STAR_DEPTH
+ , NUM_SHADER_CONSTS
+ };
// enum primarily used to control application sky settings uniforms
typedef enum
@@ -224,6 +231,8 @@ public:
void addPermutation(std::string name, std::string value);
void removePermutation(std::string name);
+ void addConstant( const LLGLSLShader::eShaderConsts shader_const );
+
//enable/disable texture channel for specified uniform
//if given texture uniform is active in the shader,
//the corresponding channel will be active upon return
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index fc24c6846d..adb3d99553 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -74,10 +74,12 @@ U32 vbo_block_size(U32 size)
U32 vbo_block_index(U32 size)
{
- return vbo_block_size(size)/LL_VBO_BLOCK_SIZE;
+ U32 blocks = vbo_block_size(size)/LL_VBO_BLOCK_SIZE; // block count reqd
+ llassert(blocks > 0);
+ return blocks - 1; // Adj index, i.e. single-block allocations are at index 0, etc
}
-const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE);
+const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE) + 1;
//============================================================================
@@ -120,7 +122,6 @@ bool LLVertexBuffer::sUseStreamDraw = true;
bool LLVertexBuffer::sUseVAO = false;
bool LLVertexBuffer::sPreferStreamDraw = false;
-
U32 LLVBOPool::genBuffer()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX
@@ -151,8 +152,9 @@ void LLVBOPool::deleteBuffer(U32 name)
LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
-: mUsage(vboUsage), mType(vboType)
+: mUsage(vboUsage), mType(vboType), mMissCountDirty(true)
{
+ mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
mMissCount.resize(LL_VBO_POOL_SEED_COUNT);
std::fill(mMissCount.begin(), mMissCount.end(), 0);
}
@@ -181,6 +183,7 @@ U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
{ //record this miss
mMissCount[i]++;
+ mMissCountDirty = true; // signal to ::seedPool()
}
if (mType == GL_ARRAY_BUFFER)
@@ -200,13 +203,13 @@ U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
ret = (U8*) ll_aligned_malloc<64>(size);
if (!ret)
{
- LL_ERRS() << "Failed to allocate "<< size << " bytes for LLVBOPool buffer " << name <<"." << LL_NEWLINE
- << "Free list size: " << mFreeList.size() // this happens if we are out of memory so a solution might be to clear some from freelist
+ LL_ERRS()
+ << "Failed to allocate " << size << " bytes for LLVBOPool buffer " << name << "." << LL_NEWLINE
+ << "Free list size: "
+ << mFreeList.size() // this happens if we are out of memory so a solution might be to clear some from freelist
<< " Allocated Bytes: " << LLVertexBuffer::sAllocatedBytes
- << " Allocated Index Bytes: " << LLVertexBuffer::sAllocatedIndexBytes
- << " Pooled Bytes: " << sBytesPooled
- << " Pooled Index Bytes: " << sIndexBytesPooled
- << LL_ENDL;
+ << " Allocated Index Bytes: " << LLVertexBuffer::sAllocatedIndexBytes << " Pooled Bytes: " << sBytesPooled
+ << " Pooled Index Bytes: " << sIndexBytesPooled << LL_ENDL;
}
}
}
@@ -234,6 +237,7 @@ U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
sIndexBytesPooled += size;
}
mFreeList[i].push_back(rec);
+ mMissCountDirty = true; // signal to ::seedPool()
}
}
else
@@ -251,6 +255,7 @@ U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
}
mFreeList[i].pop_front();
+ mMissCountDirty = true; // signal to ::seedPool()
}
return ret;
@@ -276,31 +281,27 @@ void LLVBOPool::release(U32 name, U8* buffer, U32 size)
void LLVBOPool::seedPool()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX
- U32 dummy_name = 0;
-
- if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT)
+ if (mMissCountDirty)
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("VBOPool Resize");
- mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
- }
+ U32 dummy_name = 0;
+ U32 size = LL_VBO_BLOCK_SIZE;
for (U32 i = 0; i < LL_VBO_POOL_SEED_COUNT; i++)
{
if (mMissCount[i] > mFreeList[i].size())
{
- U32 size = i*LL_VBO_BLOCK_SIZE;
-
S32 count = mMissCount[i] - mFreeList[i].size();
for (U32 j = 0; j < count; ++j)
{
allocate(dummy_name, size, true);
}
}
+ size += LL_VBO_BLOCK_SIZE;
+ }
+ mMissCountDirty = false;
}
}
-
-
void LLVBOPool::cleanup()
{
U32 size = LL_VBO_BLOCK_SIZE;
@@ -478,7 +479,7 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos)
}
gGL.end();
gGL.flush();
-}
+ }
//static
void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp)
@@ -514,7 +515,7 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
U16 idx = indicesp[i];
gGL.vertex3fv(pos[idx].getF32ptr());
}
- }
+}
gGL.end();
gGL.flush();
}
@@ -709,10 +710,10 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
#ifndef LL_RELEASE_FOR_DOWNLOAD
llassert(mNumVerts >= 0);
- if (first >= (U32)mNumVerts ||
- first + count > (U32)mNumVerts)
+ if (first >= (U32) mNumVerts ||
+ first + count > (U32) mNumVerts)
{
- LL_ERRS() << "Bad vertex buffer draw range: [" << first << ", " << first + count << "]" << LL_ENDL;
+ LL_ERRS() << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << LL_ENDL;
}
if (mGLArray)
@@ -792,6 +793,11 @@ void LLVertexBuffer::cleanupClass()
sStreamVBOPool.cleanup();
sDynamicVBOPool.cleanup();
sDynamicCopyVBOPool.cleanup();
+
+ llassert(0 == LLVBOPool::sBytesPooled);
+ llassert(0 == LLVBOPool::sIndexBytesPooled);
+ llassert(0 == sAllocatedBytes);
+ llassert(0 == sAllocatedIndexBytes);
}
//----------------------------------------------------------------------------
@@ -2381,10 +2387,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
}
llglassertok();
-}
+ }
void LLVertexBuffer::setupVertexBufferFast(U32 data_mask)
-{
+ {
U8* base = (U8*)mAlignedOffset;
if (data_mask & MAP_NORMAL)
@@ -2472,7 +2478,7 @@ void LLVertexBuffer::setupVertexBufferFast(U32 data_mask)
void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
}
-}
+ }
LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
: mType(type), mIndex(index), mCount(count)
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index e846ab70e2..4d73cf07c0 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -88,6 +88,7 @@ public:
typedef std::list<Record> record_list_t;
std::vector<record_list_t> mFreeList;
std::vector<U32> mMissCount;
+ bool mMissCountDirty; // flag any changes to mFreeList or mMissCount
//used to avoid calling glGenBuffers for every VBO creation
static U32 sNamePool[1024];
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
deleted file mode 100644
index bbdc8fdd1c..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * @file avatarAlphaNoColorV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-
-mat4 getSkinnedTransform();
-void calcAtmospherics(vec3 inPositionEye);
-
-float calcDirectionalLight(vec3 n, vec3 l);
-
-vec3 atmosAmbient();
-vec3 atmosAffectDirectionalLight(float lightIntensity);
-
-VARYING vec3 vary_position;
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_pointlight_col;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_norm;
-
-
-uniform float near_clip;
-
-uniform vec4 color;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight);
-
-void main()
-{
- vary_texcoord0 = texcoord0;
-
- vec4 pos;
- vec3 norm;
-
- mat4 trans = getSkinnedTransform();
- vec4 pos_in = vec4(position.xyz, 1.0);
- pos.x = dot(trans[0], pos_in);
- pos.y = dot(trans[1], pos_in);
- pos.z = dot(trans[2], pos_in);
- pos.w = 1.0;
-
- norm.x = dot(trans[0].xyz, normal);
- norm.y = dot(trans[1].xyz, normal);
- norm.z = dot(trans[2].xyz, normal);
- norm = normalize(norm);
- vary_norm = norm;
-
- vec4 frag_pos = projection_matrix * pos;
- gl_Position = frag_pos;
-
- vary_position = pos.xyz;
-
- calcAtmospherics(pos.xyz);
-
- vec4 col = vec4(0.0, 0.0, 0.0, 1.0);
-
- // Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
-
- vary_pointlight_col = col.rgb*color.rgb;
-
- col.rgb = vec3(0,0,0);
-
- // Add windlight lights
- col.rgb = atmosAmbient();
-
- vary_ambient = col.rgb*color.rgb;
- vary_directional = color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), 0.0));
-
- col.rgb = col.rgb * color.rgb;
-
- vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
-}
-
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
index 788ce4a47b..b45dfcd550 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
@@ -126,6 +126,6 @@ void main()
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
frag_data[2] = vec4(0,0,0,GBUFFER_FLAG_SKIP_ATMOS);
- gl_FragDepth = 0.99995f;
+ gl_FragDepth = LL_SHADER_CONST_CLOUD_MOON_DEPTH; // SL-14113 Stars and Clouds need same depth
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
index b4044353b4..7032c45603 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
@@ -54,6 +54,12 @@ void main()
fade = clamp( moon_dir.z*moon_dir.z*4.0, 0.0, 1.0 );
vec4 c = texture2D(diffuseMap, vary_texcoord0.xy);
+
+ // SL-14113 Don't write to depth; prevent moon's quad from hiding stars which should be visible
+ // Moon texture has transparent pixels <0x55,0x55,0x55,0x00>
+ if (c.a <= 2./255.) // 0.00784
+ discard;
+
// c.rgb = srgb_to_linear(c.rgb);
c.rgb *= moonlight_color.rgb;
c.rgb *= moon_brightness;
@@ -67,6 +73,6 @@ void main()
frag_data[1] = vec4(0.0);
frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_HAS_ATMOS);
- gl_FragDepth = 0.999985f;
+ gl_FragDepth = LL_SHADER_CONST_CLOUD_MOON_DEPTH; // SL-14113
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
index ef9cee3fa0..6376527273 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
@@ -46,8 +46,13 @@ float twinkle(){
return abs(d);
}
+// See:
+// ALM off: class1/environment/starsF.glsl
+// ALM on : class1/deferred/starsF.glsl
void main()
{
+ // camera above water: class1\deferred\starsF.glsl
+ // camera below water: class1\environment\starsF.glsl
vec4 col_a = texture2D(diffuseMap, vary_texcoord0.xy);
vec4 col_b = texture2D(diffuseMap, vary_texcoord0.xy);
vec4 col = mix(col_b, col_a, blend_factor);
@@ -62,6 +67,6 @@ void main()
frag_data[1] = vec4(0.0f);
frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
- gl_FragDepth = 0.99995f;
+ gl_FragDepth = LL_SHADER_CONST_STAR_DEPTH; // SL-14113 Moon Haze -- Stars need to depth test behind the moon
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
index 8863869e44..38276859a0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
@@ -70,7 +70,7 @@ void main()
d *= d;
oPosition = vec4(position, 1.0);
- oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
+// oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d); // SL-11589 remove "U" shaped horizon
vary_position = modelview_matrix * oPosition;
oPosition = modelViewProj * oPosition;
diff --git a/indra/newview/app_settings/shaders/class1/environment/moonF.glsl b/indra/newview/app_settings/shaders/class1/environment/moonF.glsl
new file mode 100644
index 0000000000..a220971f06
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/environment/moonF.glsl
@@ -0,0 +1,51 @@
+/**
+ * @file class1/environment/moonF.glsl
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D tex0;
+
+VARYING vec2 vary_texcoord0;
+
+// See:
+// AS off: class1/environment/moonF.glsl
+// ALM off: class1/windlight/moonF.glsl
+// ALM on : class1/deferred/moonF.glsl
+void main()
+{
+ vec4 color = texture2D(tex0, vary_texcoord0.xy);
+
+ // SL-14113 Don't write to depth; prevent moon's quad from hiding stars which should be visible
+ // Moon texture has transparent pixels <0x55,0x55,0x55,0x00>
+ if (color.a <= 2./255.) // 0.00784
+ discard;
+
+ frag_color = color;
+ gl_FragDepth = LL_SHADER_CONST_CLOUD_MOON_DEPTH; // SL-14113 Moon is infront of stars
+}
diff --git a/indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl b/indra/newview/app_settings/shaders/class1/environment/moonV.glsl
index 254c1d4fc2..75ad251fac 100644
--- a/indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/moonV.glsl
@@ -1,9 +1,9 @@
/**
- * @file fullbrightF.glsl
+ * @file class1\environment\moonV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2021, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,12 +22,16 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-
+uniform mat4 modelview_projection_matrix;
-void main()
+ATTRIBUTE vec3 position;
+
+VARYING vec2 vary_texcoord0;
+
+void main()
{
- fullbright_lighting();
+ gl_Position = modelview_projection_matrix * vec4(position, 1);
+ vary_texcoord0 = texcoord0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl b/indra/newview/app_settings/shaders/class1/environment/starsF.glsl
index 44f2a73e1f..e1a9cc6387 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/starsF.glsl
@@ -1,9 +1,9 @@
/**
- * @file shadowAlphaMaskF.glsl
+ * @file class1/environment/starsF.glsl
*
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
+ * Copyright (C) 2021, 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
@@ -23,8 +23,6 @@
* $/LicenseInfo$
*/
-/*[EXTRA_CODE_HERE]*/
-
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -33,23 +31,21 @@ out vec4 frag_color;
uniform sampler2D diffuseMap;
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING float pos_w;
+uniform float custom_alpha;
-VARYING float target_pos_x;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
+// See:
+// ALM off: class1/environment/starsF.glsl
+// ALM on : class1/deferred/starsF.glsl
void main()
{
- float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
+ vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
+ color.rgb = pow(color.rgb, vec3(0.45));
+ color.rgb *= vertex_color.rgb;
+ color.a *= max(custom_alpha, vertex_color.a);
- frag_color = vec4(alpha, alpha, alpha, 1);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
-#endif
+ frag_color = color;
+ gl_FragDepth = LL_SHADER_CONST_STAR_DEPTH; // SL-14113 Moon Haze -- Stars need to depth test behind the moon
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl b/indra/newview/app_settings/shaders/class1/environment/starsV.glsl
index f45c343066..6fcfec6b6a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/starsV.glsl
@@ -1,9 +1,9 @@
/**
- * @file shadowAlphaMaskV.glsl
+ * @file class1/environment/starsV.glsl
*
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
+ * Copyright (C) 2021, 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
@@ -23,45 +23,19 @@
* $/LicenseInfo$
*/
-uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec2 texcoord0;
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING float pos_w;
-
-VARYING float target_pos_x;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-void passTextureIndex();
-
void main()
{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- vec4 pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
- pos_w = pos.w;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vary_texcoord0 = texcoord0;
vertex_color = diffuse_color;
}
+
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
index a0a0e7dfca..ac400aa2a6 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
@@ -80,7 +80,7 @@ void main()
d *= d;
oPosition = vec4(position, 1.0);
- oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
+// oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d); // SL-11589 remove "U" shaped horizon
oPosition = modelViewProj * oPosition;
diff --git a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
index f03003f5e1..c4ab0c95dc 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
@@ -51,6 +51,12 @@ void main()
fade = clamp( moon_dir.z*moon_dir.z*4.0, 0.0, 1.0 );
vec4 c = texture2D(diffuseMap, vary_texcoord0.xy);
+
+ // SL-14113 Don't write to depth; prevent moon's quad from hiding stars which should be visible
+ // Moon texture has transparent pixels <0x55,0x55,0x55,0x00>
+ if (c.a <= 2./255.) // 0.00784
+ discard;
+
// c.rgb = pow(c.rgb, vec3(0.7f)); // can't use "srgb_to_linear(color.rgb)" as that is a deferred only function
c.rgb *= moonlight_color.rgb;
c.rgb *= moon_brightness;
@@ -61,5 +67,6 @@ void main()
c.rgb = scaleSoftClip(c.rgb);
frag_color = vec4(c.rgb, c.a);
+ gl_FragDepth = LL_SHADER_CONST_CLOUD_MOON_DEPTH; // SL-14113
}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
index 9c5a4903d0..6f4bdbde28 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
@@ -127,5 +127,11 @@ void main()
/// Gamma correct for WL (soft clip effect).
frag_color = vec4(color.rgb, alpha1);
+
+ // SL-14113 Moon Haze -- When the camera is underwater fix clouds clipping into moon
+ // camera above water: class1\deferred\cloudsF.glsl
+ // camera below water: class2\windlight\coudsV.glsl
+ // See: starsV.glsl, cloudsV.glsl, moonF.glsl
+ gl_FragDepth = LL_SHADER_CONST_CLOUD_MOON_DEPTH;
}
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 57a59d81c4..5de52c1daf 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -2043,6 +2043,13 @@ LLVector3d LLAgentCamera::getFocusOffsetInitial()
F32 LLAgentCamera::getCameraMaxZoomDistance()
{
+ // SL-14706 / SL-14885 TPV have relaxed camera constraints allowing you to mousewheeel zoom WAY out.
+ static LLCachedControl<bool> s_disable_camera_constraints(gSavedSettings, "DisableCameraConstraints", false);
+ if (s_disable_camera_constraints)
+ {
+ return (F32)INT_MAX;
+ }
+
// Ignore "DisableCameraConstraints", we don't want to be out of draw range when we focus onto objects or avatars
return llmin(MAX_CAMERA_DISTANCE_FROM_OBJECT,
mDrawDistance - 1, // convenience, don't hit draw limit when focusing on something
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 6e0bbb05ee..da57a3cb31 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -572,7 +572,7 @@ static void settings_modify()
LLPipeline::sRenderDeferred = TRUE; // FALSE is deprecated -- LLPipeline::sRenderBump&& gSavedSettings.getBOOL("RenderDeferred");
LLRenderTarget::sUseFBO = LLPipeline::sRenderDeferred;
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
- LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; // square lod factor to get exponential range of [1,4]
+ LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
gDebugGL = gDebugGLSession || gDebugSession;
gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
}
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index 55ebf03adc..dba400d095 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -112,20 +112,39 @@ void LLDrawPoolSky::renderSkyFace(U8 index)
return;
}
- if (index < 6) // sky tex...interp
+ if (index < LLVOSky::FACE_SUN) // sky tex...interp
{
llassert(mSkyTex);
mSkyTex[index].bindTexture(true); // bind the current tex
face->renderIndexed();
}
+ else // Moon
+ if (index == LLVOSky::FACE_MOON)
+ {
+ LLGLSPipelineDepthTestSkyBox gls_skybox(true, true); // SL-14113 Write depth for moon so stars can test if behind it
+
+ LLGLEnable blend(GL_BLEND);
+
+ // if (LLGLSLShader::sNoFixedFunction) // TODO: Necessary? is this always true? We already bailed on gPipeline.canUseWindLightShaders ... above
+ LLViewerTexture* tex = face->getTexture(LLRender::DIFFUSE_MAP);
+ if (tex)
+ {
+ gMoonProgram.bind(); // SL-14113 was gOneTextureNoColorProgram
+ gGL.getTexUnit(0)->bind(tex, true);
+ face->renderIndexed();
+ }
+ }
else // heavenly body faces, no interp...
{
+ LLGLSPipelineDepthTestSkyBox gls_skybox(true, false); // reset to previous
+
LLGLEnable blend(GL_BLEND);
LLViewerTexture* tex = face->getTexture(LLRender::DIFFUSE_MAP);
if (tex)
{
+ gOneTextureNoColorProgram.bind();
gGL.getTexUnit(0)->bind(tex, true);
face->renderIndexed();
}
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 3f39716449..21b2e56c7c 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -357,7 +357,7 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
{
#if 0
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- LLVOSky *voskyp = gSky.mVOSkyp;
+ LLVOSky *voskyp = gSky.mVOSkyp;
if (voskyp == NULL)
{
@@ -365,16 +365,16 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
}
LLGLSLShader* shader = NULL;
- if (LLPipeline::sUnderWaterRender)
- {
- shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
- }
- else
- {
- shader = &gObjectSimpleNonIndexedTexGenProgram;
- }
+ if (LLPipeline::sUnderWaterRender)
+ {
+ shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
+ }
+ else
+ {
+ shader = &gObjectSimpleNonIndexedTexGenProgram;
+ }
- shader->bind();
+ shader->bind();
stop_glerror();
@@ -508,9 +508,9 @@ void LLDrawPoolWater::renderWater()
LLColor3 light_diffuse(0, 0, 0);
F32 light_exp = 0.0f;
- LLEnvironment & environment = LLEnvironment::instance();
- LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
- LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
LLVector3 light_dir = environment.getLightDirection();
bool sun_up = environment.getIsSunUp();
bool moon_up = environment.getIsMoonUp();
@@ -535,15 +535,15 @@ void LLDrawPoolWater::renderWater()
F32 ground_proj_sq = light_dir.mV[0] * light_dir.mV[0] + light_dir.mV[1] * light_dir.mV[1];
light_exp = llmax(32.f, 256.f * powf(ground_proj_sq, 16.0f));
if (0.f < light_diffuse.normalize()) // Normalizing a color? Puzzling...
- {
+ {
light_diffuse *= (1.5f + (6.f * ground_proj_sq));
}
// set up normal maps filtering
for (auto norm_map : mWaterNormp)
- {
+ {
if (norm_map) norm_map->setFilteringOption(has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
- }
+ }
LLColor4 specular(sun_up ? psky->getSunlightColor() : psky->getMoonlightColor());
F32 phase_time = (F32) LLFrameTimer::getElapsedSeconds() * 0.5f;
@@ -570,51 +570,51 @@ void LLDrawPoolWater::renderWater()
}
gPipeline.bindDeferredShader(*shader);
-
+
// bind textures for water rendering
- S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
- if (reftex > -1)
- {
- gGL.getTexUnit(reftex)->activate();
- gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
- gGL.getTexUnit(0)->activate();
- }
+ S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
+ if (reftex > -1)
+ {
+ gGL.getTexUnit(reftex)->activate();
+ gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
+ gGL.getTexUnit(0)->activate();
+ }
- // bind normal map
- S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
- S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
+ //bind normal map
+ S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
- LLViewerTexture *tex_a = mWaterNormp[0];
- LLViewerTexture *tex_b = mWaterNormp[1];
+ LLViewerTexture* tex_a = mWaterNormp[0];
+ LLViewerTexture* tex_b = mWaterNormp[1];
F32 blend_factor = pwater->getBlendFactor();
+
+ gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
-
- if (tex_a && (!tex_b || (tex_a == tex_b)))
- {
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- blend_factor = 0; // only one tex provided, no blending
- }
- else if (tex_b && !tex_a)
- {
- gGL.getTexUnit(bumpTex)->bind(tex_b);
- blend_factor = 0; // only one tex provided, no blending
- }
- else if (tex_b != tex_a)
- {
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- gGL.getTexUnit(bumpTex2)->bind(tex_b);
- }
-
- // bind reflection texture from RenderTarget
- S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ gGL.getTexUnit(bumpTex)->bind(tex_a);
+ blend_factor = 0; // only one tex provided, no blending
+ }
+ else if (tex_b && !tex_a)
+ {
+ gGL.getTexUnit(bumpTex)->bind(tex_b);
+ blend_factor = 0; // only one tex provided, no blending
+ }
+ else if (tex_b != tex_a)
+ {
+ gGL.getTexUnit(bumpTex)->bind(tex_a);
+ gGL.getTexUnit(bumpTex2)->bind(tex_b);
+ }
+
+ // bind reflection texture from RenderTarget
+ S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
S32 screenDepth = shader->enableTexture(LLShaderMgr::WATER_SCREENDEPTH);
F32 screenRes[] = {1.f / gGLViewport[2], 1.f / gGLViewport[3]};
-
- S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
+
+ S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
// set uniforms for shader
if (deferred_render)
@@ -626,26 +626,26 @@ void LLDrawPoolWater::renderWater()
}
}
- shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
- shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+ shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
+ shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
- F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
-
- if (screentex > -1)
- {
- shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
- gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
- }
+ F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
+ if (screentex > -1)
+ {
+ shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
+ gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
+ }
+
if (screenDepth > -1)
{
gGL.getTexUnit(screenDepth)->bind(&gPipeline.mWaterDis, true);
}
- if (mShaderLevel == 1)
- {
- fog_color.mV[VW] = log(fog_density) / log(2);
- }
+ if (mShaderLevel == 1)
+ {
+ fog_color.mV[VW] = log(fog_density) / log(2);
+ }
F32 water_height = environment.getWaterHeight();
F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
@@ -654,45 +654,48 @@ void LLDrawPoolWater::renderWater()
shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
+ shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, 1, fog_color_linear.mV);
- shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
- shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
+ shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
+ shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
- shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
+ shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
- shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset());
- shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier());
+ shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset());
+ shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier());
- F32 sunAngle = llmax(0.f, light_dir.mV[1]);
- F32 scaledAngle = 1.f - sunAngle;
+ F32 sunAngle = llmax(0.f, light_dir.mV[1]);
+ F32 scaledAngle = 1.f - sunAngle;
shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0);
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle);
- shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle);
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f * sunAngle);
- shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0);
+ shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle);
+ shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle);
+ shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f*sunAngle);
+ shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0);
- LLVector4 rotated_light_direction = LLEnvironment::instance().getRotatedLightNorm();
- shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
- shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ // SL-15861 This was changed from getRotatedLightNorm() as it was causing
+ // lightnorm in shaders\class1\windlight\atmosphericsFuncs.glsl in have inconsistent additive lighting for 180 degrees of the FOV.
+ LLVector4 rotated_light_direction = LLEnvironment::instance().getClampedLightNorm();
+ shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
- if (LLViewerCamera::getInstance()->cameraUnderWater())
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
- }
- else
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
- }
+ shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- LLGLDisable cullface(GL_CULL_FACE);
+ if (LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
+ }
+
+ LLGLDisable cullface(GL_CULL_FACE);
LLVOWater *water = nullptr;
for (LLFace *const &face : mDrawFace)
@@ -701,41 +704,41 @@ void LLDrawPoolWater::renderWater()
water = static_cast<LLVOWater *>(face->getViewerObject());
if (!water) continue;
- gGL.getTexUnit(diffTex)->bind(face->getTexture());
+ gGL.getTexUnit(diffTex)->bind(face->getTexture());
if ((bool)edge == (bool) water->getIsEdgePatch())
- {
- face->renderIndexed();
+ {
+ face->renderIndexed();
// Note non-void water being drawn, updates required
if (!edge) // SL-16461 remove !LLPipeline::sUseOcclusion check
- {
- sNeedsReflectionUpdate = TRUE;
- sNeedsDistortionUpdate = TRUE;
+ {
+ sNeedsReflectionUpdate = TRUE;
+ sNeedsDistortionUpdate = TRUE;
}
- }
+ }
}
- shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
- shader->disableTexture(LLShaderMgr::BUMP_MAP);
- shader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
- shader->disableTexture(LLShaderMgr::WATER_REFTEX);
- shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
+ shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+ shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
+ shader->disableTexture(LLShaderMgr::BUMP_MAP);
+ shader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
+ shader->disableTexture(LLShaderMgr::WATER_REFTEX);
+ shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
// clean up
gPipeline.unbindDeferredShader(*shader);
gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
- }
+ }
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- if (!deferred_render)
- {
- gGL.setColorMask(true, false);
- }
+ gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+ if (!deferred_render)
+ {
+ gGL.setColorMask(true, false);
+ }
}
LLViewerTexture *LLDrawPoolWater::getDebugTexture()
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 6678e244b9..4bd7536964 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -266,15 +266,15 @@ void LLDrawPoolWLSky::renderStars(const LLVector3& camPosLocal) const
gGL.pushMatrix();
gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
- gCustomAlphaProgram.bind();
- gCustomAlphaProgram.uniform1f(sCustomAlpha, star_alpha.mV[3]);
+ gStarsProgram.bind();
+ gStarsProgram.uniform1f(sCustomAlpha, star_alpha.mV[3]);
gSky.mVOWLSkyp->drawStars();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.popMatrix();
- gCustomAlphaProgram.unbind();
-}
+ gStarsProgram.unbind(); // SL-14113 was gCustomAlphaProgram
+ }
void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
{
@@ -319,6 +319,7 @@ void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
gGL.pushMatrix();
gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
+ gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
gDeferredStarProgram.uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
if (LLPipeline::sReflectionRender)
@@ -453,7 +454,8 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
{
if (!gSky.mVOSkyp) return;
- LLGLSPipelineBlendSkyBox gls_skybox(true, false);
+ //LLGLSPipelineBlendSkyBox gls_skybox(true, false);
+ LLGLSPipelineBlendSkyBox gls_skybox(true, true); // SL-14113 we need moon to write to depth to clip stars behind
LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
gGL.pushMatrix();
@@ -583,8 +585,8 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass)
if (gPipeline.canUseWindLightShaders())
{
renderSkyHazeDeferred(origin, camHeightLocal);
- renderStarsDeferred(origin);
renderHeavenlyBodies();
+ renderStarsDeferred(origin);
renderSkyCloudsDeferred(origin, camHeightLocal, cloud_shader);
}
gGL.setColorMask(true, true);
@@ -602,8 +604,8 @@ void LLDrawPoolWLSky::render(S32 pass)
LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
renderSkyHaze(origin, camHeightLocal);
+ renderHeavenlyBodies();
renderStars(origin);
- renderHeavenlyBodies();
renderSkyClouds(origin, camHeightLocal, cloud_shader);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 9e2d28f29e..ff9f767940 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -74,7 +74,7 @@ LLVector4 gShinyOrigin;
LLGLSLShader gOcclusionProgram;
LLGLSLShader gSkinnedOcclusionProgram;
LLGLSLShader gOcclusionCubeProgram;
-LLGLSLShader gCustomAlphaProgram;
+LLGLSLShader gCustomAlphaProgram; // SL-14113 This used to be used for the stars with Atmospheric Shaders: OFF
LLGLSLShader gGlowCombineProgram;
LLGLSLShader gSplatTextureRectProgram;
LLGLSLShader gReflectionMipProgram;
@@ -143,6 +143,8 @@ LLGLSLShader gObjectAlphaMaskNoColorProgram;
LLGLSLShader gObjectAlphaMaskNoColorWaterProgram;
//environment shaders
+LLGLSLShader gMoonProgram;
+LLGLSLShader gStarsProgram;
LLGLSLShader gTerrainProgram;
LLGLSLShader gTerrainWaterProgram;
LLGLSLShader gWaterProgram;
@@ -753,6 +755,9 @@ void LLViewerShaderMgr::unloadShaders()
gWaterProgram.unload();
gWaterEdgeProgram.unload();
gUnderWaterProgram.unload();
+
+ gMoonProgram.unload();
+ gStarsProgram.unload();
gTerrainProgram.unload();
gTerrainWaterProgram.unload();
gGlowProgram.unload();
@@ -986,6 +991,34 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()
llassert(success);
}
+ if (success)
+ {
+ gStarsProgram.mName = "Environment Stars Shader";
+ gStarsProgram.mShaderFiles.clear();
+ gStarsProgram.mShaderFiles.push_back(make_pair("environment/starsV.glsl", GL_VERTEX_SHADER_ARB));
+ gStarsProgram.mShaderFiles.push_back(make_pair("environment/starsF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gStarsProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT];
+ gStarsProgram.addConstant( LLGLSLShader::SHADER_CONST_STAR_DEPTH ); // SL-14113
+ success = gStarsProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gMoonProgram.mName = "Environment Moon Shader";
+ gMoonProgram.mShaderFiles.clear();
+ gMoonProgram.mShaderFiles.push_back(make_pair("environment/moonV.glsl", GL_VERTEX_SHADER_ARB));
+ gMoonProgram.mShaderFiles.push_back(make_pair("environment/moonF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gMoonProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT];
+ gMoonProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113
+ success = gMoonProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gMoonProgram.bind();
+ gMoonProgram.uniform1i(sTex0, 0);
+ }
+ }
+
if (!success)
{
mShaderLevel[SHADER_ENVIRONMENT] = 0;
@@ -2801,6 +2834,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ gDeferredWLCloudProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113
success = gDeferredWLCloudProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2840,6 +2874,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ gDeferredWLMoonProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113
success = gDeferredWLMoonProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2852,6 +2887,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER));
gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ gDeferredStarProgram.addConstant( LLGLSLShader::SHADER_CONST_STAR_DEPTH ); // SL-14113
success = gDeferredStarProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -3901,6 +3937,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER));
gWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ gWLCloudProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113
success = gWLCloudProgram.createShader(NULL, NULL);
}
@@ -3937,6 +3974,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
gWLMoonProgram.mShaderFiles.push_back(make_pair("windlight/moonF.glsl", GL_FRAGMENT_SHADER));
gWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
gWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ gWLMoonProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113
success = gWLMoonProgram.createShader(NULL, NULL);
}
#endif
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 4ed6b02728..e32051f830 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -211,6 +211,8 @@ extern LLGLSLShader gObjectShinyProgram;
extern LLGLSLShader gObjectShinyWaterProgram;
//environment shaders
+extern LLGLSLShader gMoonProgram;
+extern LLGLSLShader gStarsProgram;
extern LLGLSLShader gTerrainProgram;
extern LLGLSLShader gTerrainWaterProgram;
extern LLGLSLShader gWaterProgram;
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 32fb7c13a9..ee39b7d02f 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -65,6 +65,53 @@
#include "llinventorymodel.h"
#include "lluiusage.h"
+// "Minimal Vulkan" to get max API Version
+
+// Calls
+ #if defined(_WIN32)
+ #define VKAPI_ATTR
+ #define VKAPI_CALL __stdcall
+ #define VKAPI_PTR VKAPI_CALL
+ #else
+ #define VKAPI_ATTR
+ #define VKAPI_CALL
+ #define VKAPI_PTR
+ #endif // _WIN32
+
+// Macros
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // <variant> <-------major-------><-----------minor-----------> <--------------patch-------------->
+ // 0x7 0x7F 0x3FF 0xFFF
+ #define VK_API_VERSION_MAJOR( version) (((uint32_t)(version) >> 22) & 0x07FU) // 7 bits
+ #define VK_API_VERSION_MINOR( version) (((uint32_t)(version) >> 12) & 0x3FFU) // 10 bits
+ #define VK_API_VERSION_PATCH( version) (((uint32_t)(version) ) & 0xFFFU) // 12 bits
+ #define VK_API_VERSION_VARIANT(version) (((uint32_t)(version) >> 29) & 0x007U) // 3 bits
+
+ // NOTE: variant is first parameter! This is to match vulkan/vulkan_core.h
+ #define VK_MAKE_API_VERSION(variant, major, minor, patch) (0\
+ | (((uint32_t)(major & 0x07FU)) << 22) \
+ | (((uint32_t)(minor & 0x3FFU)) << 12) \
+ | (((uint32_t)(patch & 0xFFFU)) ) \
+ | (((uint32_t)(variant & 0x007U)) << 29) )
+
+ #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
+
+// Types
+ VK_DEFINE_HANDLE(VkInstance);
+
+ typedef enum VkResult
+ {
+ VK_SUCCESS = 0,
+ VK_RESULT_MAX_ENUM = 0x7FFFFFFF
+ } VkResult;
+
+// Prototypes
+ typedef void (VKAPI_PTR *PFN_vkVoidFunction )(void);
+ typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr )(VkInstance instance, const char* pName);
+ typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceVersion)(uint32_t* pApiVersion);
+
namespace LLStatViewer
{
@@ -592,19 +639,76 @@ void send_viewer_stats(bool include_preferences)
// detailed information on versions and extensions can come later.
static bool vulkan_oneshot = false;
static bool vulkan_detected = false;
+ static std::string vulkan_max_api_version( "0.0" ); // Unknown/None
if (!vulkan_oneshot)
{
- HMODULE vulkan_loader = LoadLibraryExA("vulkan-1.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
+ // The 32-bit and 64-bit versions normally exist in:
+ // C:\Windows\System32
+ // C:\Windows\SysWOW64
+ HMODULE vulkan_loader = LoadLibraryA("vulkan-1.dll");
if (NULL != vulkan_loader)
{
vulkan_detected = true;
+ vulkan_max_api_version = "1.0"; // We have at least 1.0. See the note about vkEnumerateInstanceVersion() below.
+
+ // We use Run-Time Dynamic Linking (via GetProcAddress()) instead of Load-Time Dynamic Linking (via directly calling vkGetInstanceProcAddr()).
+ // This allows us to:
+ // a) not need the header: #include <vulkan/vulkan.h>
+ // (and not need to set the corresponding "Additional Include Directories" as long as we provide the equivalent Vulkan types/prototypes/etc.)
+ // b) not need to link to: vulkan-1.lib
+ // (and not need to set the corresponding "Additional Library Directories")
+ // The former will allow Second Life to start and run even if the vulkan.dll is missing.
+ // The latter will require us to:
+ // a) link with vulkan-1.lib
+ // b) cause a System Error at startup if the .dll is not found:
+ // "The code execution cannot proceed because vulkan-1.dll was not found."
+ //
+ // See:
+ // https://docs.microsoft.com/en-us/windows/win32/dlls/using-run-time-dynamic-linking
+ // https://docs.microsoft.com/en-us/windows/win32/dlls/run-time-dynamic-linking
+
+ // NOTE: Technically we can use GetProcAddress() as a replacement for vkGetInstanceProcAddr()
+ // but the canonical recommendation (mandate?) is to use vkGetInstanceProcAddr().
+ PFN_vkGetInstanceProcAddr pGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) GetProcAddress(vulkan_loader, "vkGetInstanceProcAddr");
+ if(pGetInstanceProcAddr)
+ {
+ // Check for vkEnumerateInstanceVersion. If it exists then we have at least 1.1 and can query the max API version.
+ // NOTE: Each VkPhysicalDevice that supports Vulkan has its own VkPhysicalDeviceProperties.apiVersion which is separate from the max API version!
+ // See: https://www.lunarg.com/wp-content/uploads/2019/02/Vulkan-1.1-Compatibility-Statement_01_19.pdf
+ PFN_vkEnumerateInstanceVersion pEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) pGetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion");
+ if(pEnumerateInstanceVersion)
+ {
+ uint32_t version = VK_MAKE_API_VERSION(0,1,1,0); // e.g. 4202631 = 1.2.135.0
+ VkResult status = pEnumerateInstanceVersion( &version );
+ if (status != VK_SUCCESS)
+ {
+ LL_INFOS("Vulkan") << "Failed to get Vulkan version. Assuming 1.0" << LL_ENDL;
+ }
+ else
+ {
+ // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#extendingvulkan-coreversions-versionnumbers
+ int major = VK_API_VERSION_MAJOR ( version );
+ int minor = VK_API_VERSION_MINOR ( version );
+ int patch = VK_API_VERSION_PATCH ( version );
+ int variant = VK_API_VERSION_VARIANT( version );
+
+ vulkan_max_api_version = llformat( "%d.%d.%d.%d", major, minor, patch, variant );
+ LL_INFOS("Vulkan") << "Vulkan API version: " << vulkan_max_api_version << ", Raw version: " << version << LL_ENDL;
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS("Vulkan") << "FAILED to get Vulkan vkGetInstanceProcAddr()!" << LL_ENDL;
+ }
FreeLibrary(vulkan_loader);
}
vulkan_oneshot = true;
}
misc["string_1"] = vulkan_detected ? llformat("Vulkan driver is detected") : llformat("No Vulkan driver detected");
+ misc["VulkanMaxApiVersion"] = vulkan_max_api_version;
#else
misc["string_1"] = llformat("Unused");