summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llgl.cpp2
-rw-r--r--indra/llrender/llglslshader.cpp26
-rw-r--r--indra/llrender/llglslshader.h11
-rw-r--r--indra/llrender/llvertexbuffer.cpp239
-rw-r--r--indra/llrender/llvertexbuffer.h1
5 files changed, 160 insertions, 119 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 43fedeca64..33cd840e50 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -559,7 +559,7 @@ bool LLGLManager::initGL()
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
for (GLint i = 0; i < count; ++i)
{
- std::string ext((const char*) glGetStringi(GL_EXTENSIONS, i));
+ std::string ext = ll_safe_string((const char*) glGetStringi(GL_EXTENSIONS, i));
str << ext << " ";
LL_DEBUGS("GLExtensions") << ext << LL_ENDL;
}
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 4351f6e2c8..d3942c7552 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -62,6 +62,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;
@@ -763,6 +778,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();
@@ -1407,7 +1427,11 @@ GLint LLGLSLShader::getUniformLocation(U32 index)
GLint ret = -1;
if (mProgramObject)
{
- llassert(index < mUniform.size());
+ if (index >= mUniform.size())
+ {
+ LL_WARNS_ONCE("Shader") << "Uniform index " << index << " out of bounds " << (S32)mUniform.size() << LL_ENDL;
+ return ret;
+ }
return mUniform[index];
}
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 7cf6d3c941..e2d0031740 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -67,6 +67,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
{
@@ -149,7 +156,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 7d2b09ca4a..93967b128d 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -68,16 +68,18 @@ const U32 LL_VBO_POOL_MAX_SEED_SIZE = 256*1024;
U32 vbo_block_size(U32 size)
{ //what block size will fit size?
- U32 mod = size % LL_VBO_BLOCK_SIZE;
- return mod == 0 ? size : size + (LL_VBO_BLOCK_SIZE-mod);
+ U32 mod = size % LL_VBO_BLOCK_SIZE;
+ return mod == 0 ? size : size + (LL_VBO_BLOCK_SIZE-mod);
}
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;
//============================================================================
@@ -118,7 +120,6 @@ bool LLVertexBuffer::sUseStreamDraw = true;
bool LLVertexBuffer::sUseVAO = false;
bool LLVertexBuffer::sPreferStreamDraw = false;
-
U32 LLVBOPool::genBuffer()
{
U32 ret = 0;
@@ -144,108 +145,112 @@ void LLVBOPool::deleteBuffer(U32 name)
LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
-: mUsage(vboUsage), mType(vboType)
+: mUsage(vboUsage), mType(vboType), mMissCountDirty(true)
{
- mMissCount.resize(LL_VBO_POOL_SEED_COUNT);
+ mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
+ mMissCount.resize(LL_VBO_POOL_SEED_COUNT);
std::fill(mMissCount.begin(), mMissCount.end(), 0);
}
-volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
+volatile U8 *LLVBOPool::allocate(U32 &name, U32 size, bool for_seed)
{
- llassert(vbo_block_size(size) == size);
-
- volatile U8* ret = NULL;
+ llassert(vbo_block_size(size) == size);
- U32 i = vbo_block_index(size);
+ volatile U8 *ret = NULL;
- if (mFreeList.size() <= i)
- {
- mFreeList.resize(i+1);
- }
+ U32 i = vbo_block_index(size);
- if (mFreeList[i].empty() || for_seed)
- {
- //make a new buffer
- name = genBuffer();
-
- glBindBufferARB(mType, name);
+ if (mFreeList.size() <= i)
+ {
+ mFreeList.resize(i + 1);
+ }
- if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
- { //record this miss
- mMissCount[i]++;
- }
+ if (mFreeList[i].empty() || for_seed)
+ {
+ // make a new buffer
+ name = genBuffer();
- if (mType == GL_ARRAY_BUFFER_ARB)
- {
- LLVertexBuffer::sAllocatedBytes += size;
- }
- else
- {
- LLVertexBuffer::sAllocatedIndexBytes += size;
- }
+ glBindBufferARB(mType, name);
- if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
- {
- glBufferDataARB(mType, size, 0, mUsage);
- if (mUsage != GL_DYNAMIC_COPY_ARB)
- { //data will be provided by application
- 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
- << " Allocated Bytes: " << LLVertexBuffer::sAllocatedBytes
- << " Allocated Index Bytes: " << LLVertexBuffer::sAllocatedIndexBytes
- << " Pooled Bytes: " << sBytesPooled
- << " Pooled Index Bytes: " << sIndexBytesPooled
- << LL_ENDL;
- }
- }
- }
- else
- { //always use a true hint of static draw when allocating non-client-backed buffers
- glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
- }
-
- glBindBufferARB(mType, 0);
+ if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
+ { // record this miss
+ mMissCount[i]++;
+ mMissCountDirty = true; // signal to ::seedPool()
+ }
- if (for_seed)
- { //put into pool for future use
- llassert(mFreeList.size() > i);
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ LLVertexBuffer::sAllocatedBytes += size;
+ }
+ else
+ {
+ LLVertexBuffer::sAllocatedIndexBytes += size;
+ }
- Record rec;
- rec.mGLName = name;
- rec.mClientData = ret;
-
- if (mType == GL_ARRAY_BUFFER_ARB)
- {
- sBytesPooled += size;
- }
- else
- {
- sIndexBytesPooled += size;
- }
- mFreeList[i].push_back(rec);
- }
- }
- else
- {
- name = mFreeList[i].front().mGLName;
- ret = mFreeList[i].front().mClientData;
-
- if (mType == GL_ARRAY_BUFFER_ARB)
- {
- sBytesPooled -= size;
- }
- else
- {
- sIndexBytesPooled -= size;
- }
-
- mFreeList[i].pop_front();
- }
-
- return ret;
+ if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
+ {
+ glBufferDataARB(mType, size, 0, mUsage);
+ if (mUsage != GL_DYNAMIC_COPY_ARB)
+ { // data will be provided by application
+ 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
+ << " Allocated Bytes: " << LLVertexBuffer::sAllocatedBytes
+ << " Allocated Index Bytes: " << LLVertexBuffer::sAllocatedIndexBytes << " Pooled Bytes: " << sBytesPooled
+ << " Pooled Index Bytes: " << sIndexBytesPooled << LL_ENDL;
+ }
+ }
+ }
+ else
+ { // always use a true hint of static draw when allocating non-client-backed buffers
+ glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
+ }
+
+ glBindBufferARB(mType, 0);
+
+ if (for_seed)
+ { // put into pool for future use
+ llassert(mFreeList.size() > i);
+
+ Record rec;
+ rec.mGLName = name;
+ rec.mClientData = ret;
+
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled += size;
+ }
+ else
+ {
+ sIndexBytesPooled += size;
+ }
+ mFreeList[i].push_back(rec);
+ mMissCountDirty = true; // signal to ::seedPool()
+ }
+ }
+ else
+ {
+ name = mFreeList[i].front().mGLName;
+ ret = mFreeList[i].front().mClientData;
+
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled -= size;
+ }
+ else
+ {
+ sIndexBytesPooled -= size;
+ }
+
+ mFreeList[i].pop_front();
+ mMissCountDirty = true; // signal to ::seedPool()
+ }
+
+ return ret;
}
void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
@@ -267,30 +272,27 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
void LLVBOPool::seedPool()
{
- U32 dummy_name = 0;
-
- if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT)
- {
- mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
- }
-
- 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);
- }
- }
- }
+ if (mMissCountDirty)
+ {
+ 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())
+ {
+ 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;
@@ -917,6 +919,11 @@ void LLVertexBuffer::cleanupClass()
sStreamVBOPool.cleanup();
sDynamicVBOPool.cleanup();
sDynamicCopyVBOPool.cleanup();
+
+ llassert(0 == LLVBOPool::sBytesPooled);
+ llassert(0 == LLVBOPool::sIndexBytesPooled);
+ llassert(0 == sAllocatedBytes);
+ llassert(0 == sAllocatedIndexBytes);
}
//----------------------------------------------------------------------------
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index dbe1a3687f..649fbb782c 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
};