summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llglslshader.cpp20
-rw-r--r--indra/llrender/llglslshader.h11
-rw-r--r--indra/llrender/llvertexbuffer.cpp394
-rw-r--r--indra/llrender/llvertexbuffer.h1
4 files changed, 231 insertions, 195 deletions
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 185c1450c8..3a0745106f 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;
@@ -770,6 +785,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 85e83dbcb9..83f11c050b 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -128,6 +128,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
@@ -212,7 +219,9 @@ public:
void clearPermutations();
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 6338cab96a..954b3d5fa8 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
@@ -130,7 +131,7 @@ U32 LLVBOPool::genBuffer()
glGenBuffersARB(1024, sNamePool);
sNameIdx = 1024;
}
-
+
return sNamePool[--sNameIdx];
}
@@ -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_ARB)
@@ -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
+ if (mMissCountDirty)
+ {
U32 dummy_name = 0;
-
- if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("VBOPool Resize");
- mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
- }
+ 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;
@@ -441,27 +442,27 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
data_mask = data_mask & ~MAP_TEXTURE_INDEX;
}
- for (U32 i = 0; i < TYPE_MAX; ++i)
- {
- S32 loc = i;
+ for (U32 i = 0; i < TYPE_MAX; ++i)
+ {
+ S32 loc = i;
- U32 mask = 1 << i;
+ U32 mask = 1 << i;
- if (sLastMask & (1 << i))
- { //was enabled
- if (!(data_mask & mask))
- { //needs to be disabled
- glDisableVertexAttribArrayARB(loc);
+ if (sLastMask & (1 << i))
+ { //was enabled
+ if (!(data_mask & mask))
+ { //needs to be disabled
+ glDisableVertexAttribArrayARB(loc);
+ }
}
- }
- else
- { //was disabled
- if (data_mask & mask)
- { //needs to be enabled
- glEnableVertexAttribArrayARB(loc);
+ else
+ { //was disabled
+ if (data_mask & mask)
+ { //needs to be enabled
+ glEnableVertexAttribArrayARB(loc);
+ }
}
}
- }
sLastMask = data_mask;
}
@@ -473,12 +474,12 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos)
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
gGL.begin(mode);
for (auto& v : pos)
- {
+ {
gGL.vertex3fv(v.mV);
- }
+ }
gGL.end();
gGL.flush();
-}
+ }
//static
void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp)
@@ -499,22 +500,22 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
gGL.begin(mode);
if (tc != nullptr)
- {
+ {
for (int i = 0; i < num_indices; ++i)
- {
+ {
U16 idx = indicesp[i];
gGL.texCoord2fv(tc[idx].mV);
gGL.vertex3fv(pos[idx].getF32ptr());
- }
- }
- else
- {
+ }
+ }
+ else
+ {
for (int i = 0; i < num_indices; ++i)
{
U16 idx = indicesp[i];
gGL.vertex3fv(pos[idx].getF32ptr());
- }
- }
+ }
+}
gGL.end();
gGL.flush();
}
@@ -701,48 +702,48 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
llassert(LLGLSLShader::sCurBoundShaderPtr != NULL);
- mMappable = false;
- gGL.syncMatrices();
-
+ mMappable = false;
+ gGL.syncMatrices();
+
#ifndef LL_RELEASE_FOR_DOWNLOAD
- llassert(mNumVerts >= 0);
- if (first >= (U32)mNumVerts ||
- first + count > (U32)mNumVerts)
- {
- LL_ERRS() << "Bad vertex buffer draw range: [" << first << ", " << first + count << "]" << LL_ENDL;
- }
+ llassert(mNumVerts >= 0);
+ if (first >= (U32) mNumVerts ||
+ first + count > (U32) mNumVerts)
+ {
+ LL_ERRS() << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << LL_ENDL;
+ }
- if (mGLArray)
- {
- if (mGLArray != sGLRenderArray)
- {
- LL_ERRS() << "Wrong vertex array bound." << LL_ENDL;
- }
- }
- else
- {
- if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive)
- {
- LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL;
- }
- }
+ if (mGLArray)
+ {
+ if (mGLArray != sGLRenderArray)
+ {
+ LL_ERRS() << "Wrong vertex array bound." << LL_ENDL;
+ }
+ }
+ else
+ {
+ if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive)
+ {
+ LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL;
+ }
+ }
- if (mode >= LLRender::NUM_MODES)
- {
- LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL;
- return;
- }
+ if (mode >= LLRender::NUM_MODES)
+ {
+ LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL;
+ return;
+ }
#endif
LLGLSLShader::startProfile();
- {
+ {
LL_PROFILER_GPU_ZONEC("gl.DrawArrays", 0xFF4040)
- glDrawArrays(sGLMode[mode], first, count);
+ glDrawArrays(sGLMode[mode], first, count);
}
- LLGLSLShader::stopProfile(count, mode);
+ LLGLSLShader::stopProfile(count, mode);
- stop_glerror();
- placeFence();
+ stop_glerror();
+ placeFence();
}
//static
@@ -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);
}
//----------------------------------------------------------------------------
@@ -1841,7 +1847,7 @@ void LLVertexBuffer::unmapBuffer()
#endif
}
else if (gGLManager.mHasFlushBufferRange)
- {
+ {
#ifndef LL_MESA_HEADLESS
glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER_ARB, offset, length);
#endif
@@ -1935,7 +1941,7 @@ void LLVertexBuffer::unmapBuffer()
}
}
- glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
+ glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
mMappedIndexData = NULL;
}
@@ -2392,145 +2398,145 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
LL_ERRS() << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << LL_ENDL;
}
- if (data_mask & MAP_NORMAL)
- {
- S32 loc = TYPE_NORMAL;
- void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]);
- glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr);
- }
- if (data_mask & MAP_TEXCOORD3)
- {
- S32 loc = TYPE_TEXCOORD3;
- void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]);
- glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr);
- }
- if (data_mask & MAP_TEXCOORD2)
- {
- S32 loc = TYPE_TEXCOORD2;
- void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]);
- glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr);
- }
- if (data_mask & MAP_TEXCOORD1)
- {
- S32 loc = TYPE_TEXCOORD1;
- void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
- glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
- }
- if (data_mask & MAP_TANGENT)
- {
- S32 loc = TYPE_TANGENT;
- void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
- glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
- }
- if (data_mask & MAP_TEXCOORD0)
- {
- S32 loc = TYPE_TEXCOORD0;
- void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]);
- glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr);
- }
- if (data_mask & MAP_COLOR)
- {
- S32 loc = TYPE_COLOR;
- //bind emissive instead of color pointer if emissive is present
- void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
- glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
- }
- if (data_mask & MAP_EMISSIVE)
- {
- S32 loc = TYPE_EMISSIVE;
- void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
- glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
-
- if (!(data_mask & MAP_COLOR))
- { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps
- loc = TYPE_COLOR;
+ if (data_mask & MAP_NORMAL)
+ {
+ S32 loc = TYPE_NORMAL;
+ void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]);
+ glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr);
+ }
+ if (data_mask & MAP_TEXCOORD3)
+ {
+ S32 loc = TYPE_TEXCOORD3;
+ void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]);
+ glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr);
+ }
+ if (data_mask & MAP_TEXCOORD2)
+ {
+ S32 loc = TYPE_TEXCOORD2;
+ void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]);
+ glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr);
+ }
+ if (data_mask & MAP_TEXCOORD1)
+ {
+ S32 loc = TYPE_TEXCOORD1;
+ void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
+ glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
+ }
+ if (data_mask & MAP_TANGENT)
+ {
+ S32 loc = TYPE_TANGENT;
+ void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
+ glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
+ }
+ if (data_mask & MAP_TEXCOORD0)
+ {
+ S32 loc = TYPE_TEXCOORD0;
+ void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]);
+ glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr);
+ }
+ if (data_mask & MAP_COLOR)
+ {
+ S32 loc = TYPE_COLOR;
+ //bind emissive instead of color pointer if emissive is present
+ void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
+ glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
+ }
+ if (data_mask & MAP_EMISSIVE)
+ {
+ S32 loc = TYPE_EMISSIVE;
+ void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+
+ if (!(data_mask & MAP_COLOR))
+ { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps
+ loc = TYPE_COLOR;
+ glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+ }
}
- }
- if (data_mask & MAP_WEIGHT)
- {
- S32 loc = TYPE_WEIGHT;
- void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]);
- glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
- }
- if (data_mask & MAP_WEIGHT4)
- {
- S32 loc = TYPE_WEIGHT4;
- void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]);
- glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
- }
- if (data_mask & MAP_CLOTHWEIGHT)
- {
- S32 loc = TYPE_CLOTHWEIGHT;
- void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
- glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
- }
- if (data_mask & MAP_TEXTURE_INDEX &&
- (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later
- {
+ if (data_mask & MAP_WEIGHT)
+ {
+ S32 loc = TYPE_WEIGHT;
+ void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]);
+ glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
+ }
+ if (data_mask & MAP_WEIGHT4)
+ {
+ S32 loc = TYPE_WEIGHT4;
+ void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]);
+ glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
+ }
+ if (data_mask & MAP_CLOTHWEIGHT)
+ {
+ S32 loc = TYPE_CLOTHWEIGHT;
+ void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
+ glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
+ }
+ if (data_mask & MAP_TEXTURE_INDEX &&
+ (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later
+ {
#if !LL_DARWIN
- S32 loc = TYPE_TEXTURE_INDEX;
- void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
- glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+ S32 loc = TYPE_TEXTURE_INDEX;
+ void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
+ glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
#endif
- }
- if (data_mask & MAP_VERTEX)
- {
- S32 loc = TYPE_VERTEX;
- void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
- glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
- }
+ }
+ if (data_mask & MAP_VERTEX)
+ {
+ S32 loc = TYPE_VERTEX;
+ void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
+ glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+ }
llglassertok();
-}
+ }
void LLVertexBuffer::setupVertexBufferFast(U32 data_mask)
-{
+ {
U8* base = (U8*)mAlignedOffset;
- if (data_mask & MAP_NORMAL)
- {
+ if (data_mask & MAP_NORMAL)
+ {
S32 loc = TYPE_NORMAL;
void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]);
glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr);
- }
- if (data_mask & MAP_TEXCOORD3)
- {
+ }
+ if (data_mask & MAP_TEXCOORD3)
+ {
S32 loc = TYPE_TEXCOORD3;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]);
glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr);
- }
- if (data_mask & MAP_TEXCOORD2)
- {
+ }
+ if (data_mask & MAP_TEXCOORD2)
+ {
S32 loc = TYPE_TEXCOORD2;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]);
glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr);
- }
- if (data_mask & MAP_TEXCOORD1)
- {
+ }
+ if (data_mask & MAP_TEXCOORD1)
+ {
S32 loc = TYPE_TEXCOORD1;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
- }
- if (data_mask & MAP_TANGENT)
- {
+ }
+ if (data_mask & MAP_TANGENT)
+ {
S32 loc = TYPE_TANGENT;
void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
- }
- if (data_mask & MAP_TEXCOORD0)
- {
+ }
+ if (data_mask & MAP_TEXCOORD0)
+ {
S32 loc = TYPE_TEXCOORD0;
void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]);
glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr);
- }
- if (data_mask & MAP_COLOR)
- {
+ }
+ if (data_mask & MAP_COLOR)
+ {
S32 loc = TYPE_COLOR;
//bind emissive instead of color pointer if emissive is present
void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
- }
+ }
if (data_mask & MAP_EMISSIVE)
{
S32 loc = TYPE_EMISSIVE;
@@ -2569,13 +2575,13 @@ void LLVertexBuffer::setupVertexBufferFast(U32 data_mask)
glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
#endif
}
- if (data_mask & MAP_VERTEX)
- {
+ if (data_mask & MAP_VERTEX)
+ {
S32 loc = TYPE_VERTEX;
void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
glVertexAttribPointerARB(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 baf8407fc6..3c52b30570 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];