summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llcubemaparray.cpp3
-rw-r--r--indra/llrender/llgl.cpp14
-rw-r--r--indra/llrender/llgl.h13
-rw-r--r--indra/llrender/llimagegl.cpp7
-rw-r--r--indra/llrender/llrender.cpp117
-rw-r--r--indra/llrender/llrender.h4
-rw-r--r--indra/llrender/llrender2dutils.cpp5
-rw-r--r--indra/llrender/llrendertarget.cpp197
-rw-r--r--indra/llrender/llrendertarget.h15
-rw-r--r--indra/llrender/llshadermgr.cpp20
-rw-r--r--indra/llrender/llshadermgr.h12
-rw-r--r--indra/llrender/llvertexbuffer.cpp171
12 files changed, 405 insertions, 173 deletions
diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp
index fb35e002df..e0a8782c33 100644
--- a/indra/llrender/llcubemaparray.cpp
+++ b/indra/llrender/llcubemaparray.cpp
@@ -114,6 +114,8 @@ LLCubeMapArray::LLCubeMapArray(LLCubeMapArray& lhs, U32 width, U32 count) : mTex
allocate(mWidth, lhs.mImage->getComponents(), count, lhs.mImage->getUseMipMaps(), lhs.mHDR);
// Copy each cubemap from the incoming array to the new array
+ // The call to glTexSubImage3D causes an INVALID OPERATION OpenGL error. For now we comment this..
+ /*
U32 min_count = std::min(count, lhs.mCount);
for (U32 i = 0; i < min_count * 6; ++i)
{
@@ -133,6 +135,7 @@ LLCubeMapArray::LLCubeMapArray(LLCubeMapArray& lhs, U32 width, U32 count) : mTex
glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, i, mWidth, mWidth, 1, components, GL_UNSIGNED_BYTE, scaled_image->getData());
}
}
+ */
}
LLCubeMapArray::~LLCubeMapArray()
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index ac66faaf5a..cc619e2086 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -2279,26 +2279,28 @@ void rotate_quat(LLQuaternion& rotation)
void flush_glerror()
{
+ if(!gDebugGL) return;
glGetError();
}
-//this function outputs gl error to the log file, does not crash the code.
-void log_glerror()
+void log_glerror(std::string comment)
{
+ if(!gDebugGL) return;
+
if (LL_UNLIKELY(!gGLManager.mInited))
{
return ;
}
- // Create or update texture to be used with this data
+
GLenum error;
error = glGetError();
- while (LL_UNLIKELY(error))
+ if (error != GL_NO_ERROR)
{
#if GLU_VERSION_1_1
GLubyte const * gl_error_msg = gluErrorString(error);
if (NULL != gl_error_msg)
{
- LL_WARNS() << "GL Error: " << error << " GL Error String: " << gl_error_msg << LL_ENDL ;
+ LL_WARNS() << "GL Error (" << comment << ")" << error << ": " << gl_error_msg << LL_ENDL;
}
else
#endif // GLU_VERSION_1_1
@@ -2307,7 +2309,6 @@ void log_glerror()
// you'll probably have to grep for the number in glext.h.
LL_WARNS() << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL;
}
- error = glGetError();
}
}
@@ -2385,6 +2386,7 @@ void assert_glerror()
void clear_glerror()
{
+ if(!gDebugGL) return;
glGetError();
glGetError();
}
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index bf8368a7b3..130b06f9df 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -154,17 +154,20 @@ void rotate_quat(LLQuaternion& rotation);
void flush_glerror(); // Flush GL errors when we know we're handling them correctly.
-void log_glerror();
+void log_glerror(std::string comment);
void assert_glerror();
void clear_glerror();
-#if !LL_RELEASE_FOR_DOWNLOAD
-# define stop_glerror() assert_glerror()
-# define llglassertok() assert_glerror()
-# define STOP_GLERROR stop_glerror()
+//#if !LL_RELEASE_FOR_DOWNLOAD
+#if 1
+# define LOG_GLERROR(COMMENT) log_glerror(COMMENT)
+# define stop_glerror() log_glerror("stop")
+# define llglassertok() log_glerror("ASSERTOK")
+# define STOP_GLERROR log_glerror("STOP")
#else
+# define LOG_GLERROR(COMMENT)
# define stop_glerror()
# define llglassertok()
# define STOP_GLERROR
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 558c3b062a..42af68c276 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -358,6 +358,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat)
#endif
case GL_DEPTH_COMPONENT: return 24;
case GL_DEPTH_COMPONENT24: return 24;
+ case GL_RGBA16: return 64;
case GL_R16F: return 16;
case GL_RG16F: return 32;
case GL_RGB16F: return 48;
@@ -1290,7 +1291,7 @@ bool LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
{
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
mGLTextureCreated = true;
- stop_glerror();
+ LOG_GLERROR("LLImageGL::setSubImageFromFrameBuffer()");
return true;
}
else
@@ -2583,6 +2584,8 @@ bool LLImageGL::scaleDown(S32 desired_discard)
return false;
}
+ //LL_WARNS() << "scaleDown" << LL_ENDL;
+
S32 mip = desired_discard - mCurrentDiscardLevel;
S32 desired_width = getWidth(desired_discard);
@@ -2600,6 +2603,7 @@ bool LLImageGL::scaleDown(S32 desired_discard)
free_tex_image(mTexName);
glTexImage2D(mTarget, 0, mFormatInternal, desired_width, desired_height, 0, mFormatPrimary, mFormatType, nullptr);
glCopyTexSubImage2D(mTarget, 0, 0, 0, 0, 0, desired_width, desired_height);
+ LOG_GLERROR("LLImageGL::scaleDown() - glCopyTexSubImage2D");
alloc_tex_image(desired_width, desired_height, mFormatInternal, 1);
mTexOptionsDirty = true;
@@ -2609,6 +2613,7 @@ bool LLImageGL::scaleDown(S32 desired_discard)
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap");
gGL.getTexUnit(0)->bind(this);
glGenerateMipmap(mTarget);
+ LOG_GLERROR("LLImageGL::scaleDown() - glGenerateMipmap");
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
}
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index cbb178b6f8..d0e268f08c 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1,4 +1,4 @@
- /**
+/**
* @file llrender.cpp
* @brief LLRender implementation
*
@@ -139,21 +139,21 @@ U32 LLTexUnit::getInternalType(eTextureType type)
void LLTexUnit::refreshState(void)
{
- // We set dirty to true so that the tex unit knows to ignore caching
- // and we reset the cached tex unit state
+// We set dirty to true so that the tex unit knows to ignore caching
+// and we reset the cached tex unit state
- gGL.flush();
+gGL.flush();
- glActiveTexture(GL_TEXTURE0 + mIndex);
+glActiveTexture(GL_TEXTURE0 + mIndex);
- if (mCurrTexType != TT_NONE)
- {
- glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture);
- }
- else
- {
- glBindTexture(GL_TEXTURE_2D, 0);
- }
+if (mCurrTexType != TT_NONE)
+{
+ glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture);
+}
+else
+{
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
}
void LLTexUnit::activate(void)
@@ -203,6 +203,7 @@ void LLTexUnit::bindFast(LLTexture* texture)
glActiveTexture(GL_TEXTURE0 + mIndex);
gGL.mCurrTextureUnitIndex = mIndex;
mCurrTexture = gl_tex->getTexName();
+ mCurrTexType = gl_tex->getTarget();
if (!mCurrTexture)
{
LL_PROFILE_ZONE_NAMED("MISSING TEXTURE");
@@ -479,41 +480,49 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio
{
if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE) return;
+ GLenum target = sGLTextureType[mCurrTexType];
+
+ if (mCurrTexType == LLTexUnit::TT_NONE)
+ {
+ LL_WARNS() << "setTextureFilteringOption() Error: mCurrTexType==TT_NONE texture: " << mCurrTexture << LL_ENDL;
+ gGL.debugTexUnits();
+ }
+
gGL.flush();
if (option == TFO_POINT)
{
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
else
{
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
if (option >= TFO_TRILINEAR && mHasMipMaps)
{
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
else if (option >= TFO_BILINEAR)
{
if (mHasMipMaps)
{
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
}
else
{
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
}
else
{
if (mHasMipMaps)
{
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
}
else
{
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
}
@@ -521,11 +530,11 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio
{
if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC)
{
- glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGLManager.mMaxAnisotropy);
+ glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, gGLManager.mMaxAnisotropy);
}
else
{
- glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
+ glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
}
}
}
@@ -651,12 +660,12 @@ void LLTexUnit::debugTextureUnit(void)
LLLightState::LLLightState(S32 index)
: mIndex(index),
- mEnabled(false),
- mConstantAtten(1.f),
- mLinearAtten(0.f),
- mQuadraticAtten(0.f),
- mSpotExponent(0.f),
- mSpotCutoff(180.f)
+mEnabled(false),
+mConstantAtten(1.f),
+mLinearAtten(0.f),
+mQuadraticAtten(0.f),
+mSpotExponent(0.f),
+mSpotCutoff(180.f)
{
if (mIndex == 0)
{
@@ -815,7 +824,7 @@ void LLLightState::setSpotDirection(const LLVector3& direction)
}
LLRender::LLRender()
- : mDirty(false),
+: mDirty(false),
mCount(0),
mMode(LLRender::TRIANGLES),
mCurrTextureUnitIndex(0)
@@ -908,13 +917,12 @@ bool LLRender::init(bool needs_vertex_buffer)
void LLRender::initVertexBuffer()
{
llassert_always(mBuffer.isNull());
- stop_glerror();
mBuffer = new LLVertexBuffer(immediate_mask);
- mBuffer->allocateBuffer(4096, 0);
+ mBuffer->allocateBuffer(16384, 0);
mBuffer->getVertexStrider(mVerticesp);
mBuffer->getTexCoord0Strider(mTexcoordsp);
mBuffer->getColorStrider(mColorsp);
- stop_glerror();
+ LOG_GLERROR("LLRender::initVertexBuffer()");
}
void LLRender::resetVertexBuffer()
@@ -1000,7 +1008,6 @@ void LLRender::syncLightState()
void LLRender::syncMatrices()
{
- STOP_GLERROR;
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
static const U32 name[] =
@@ -1145,7 +1152,7 @@ void LLRender::syncMatrices()
syncLightState();
}
}
- STOP_GLERROR;
+ LOG_GLERROR("LLRender::syncMatrices()");
}
void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
@@ -1448,7 +1455,7 @@ void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)
}
void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
- eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor)
+ eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor)
{
llassert(color_sfactor < BF_UNDEF);
llassert(color_dfactor < BF_UNDEF);
@@ -1465,7 +1472,7 @@ void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
flush();
glBlendFuncSeparate(sGLBlendFactor[color_sfactor], sGLBlendFactor[color_dfactor],
- sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]);
+ sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]);
}
}
@@ -1555,7 +1562,7 @@ void LLRender::begin(const GLuint& mode)
mMode == LLRender::TRIANGLES ||
mMode == LLRender::POINTS)
{
- flush();
+ flush("LLRender::begin");
}
else if (mCount != 0)
{
@@ -1566,7 +1573,7 @@ void LLRender::begin(const GLuint& mode)
}
}
-void LLRender::end()
+void LLRender::end(std::string comment_)
{
if (mCount == 0)
{
@@ -1579,13 +1586,13 @@ void LLRender::end()
mMode != LLRender::POINTS) ||
mCount > 2048)
{
- flush();
+ flush("from end " + comment_);
}
}
-void LLRender::flush()
+void LLRender::flush(std::string comment_)
{
- STOP_GLERROR;
+ LOG_GLERROR("LLRender::flush() begin " + comment_);
if (mCount > 0)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
@@ -1604,8 +1611,8 @@ void LLRender::flush()
{
if (mCount%3 != 0)
{
- count -= (mCount % 3);
- LL_WARNS() << "Incomplete triangle requested." << LL_ENDL;
+ count -= (mCount % 3);
+ LL_WARNS() << "Incomplete triangle requested." << LL_ENDL;
}
}
@@ -1655,6 +1662,8 @@ void LLRender::flush()
resetStriders(count);
}
+
+ LOG_GLERROR("LLRender::flush() end " + comment_);
}
LLVertexBuffer* LLRender::bufferfromCache(U32 attribute_mask, U32 count)
@@ -2026,7 +2035,8 @@ void LLRender::debugTexUnits(void)
std::string active_enabled = "false";
for (U32 i = 0; i < mTexUnits.size(); i++)
{
- if (getTexUnit(i)->mCurrTexType != LLTexUnit::TT_NONE)
+ //if (getTexUnit(i)->mCurrTexType != LLTexUnit::TT_NONE)
+ if(1)
{
if (i == mCurrTextureUnitIndex) active_enabled = "true";
LL_INFOS("TextureUnit") << "TexUnit: " << i << " Enabled" << LL_ENDL;
@@ -2044,8 +2054,19 @@ void LLRender::debugTexUnits(void)
case LLTexUnit::TT_CUBE_MAP:
LL_CONT << "Cube Map";
break;
+ case LLTexUnit::TT_CUBE_MAP_ARRAY:
+ LL_CONT << "Cube Map Array";
+ break;
+
+ case LLTexUnit::TT_MULTISAMPLE_TEXTURE:
+ LL_CONT << "Multisample Texture";
+ break;
+
+ case LLTexUnit::TT_TEXTURE_3D:
+ LL_CONT << "Texture 3D";
+ break;
default:
- LL_CONT << "ARGH!!! NONE!";
+ LL_CONT << "ARGH!!! NONE! -> type = " << getTexUnit(i)->mCurrTexType;
break;
}
LL_CONT << ", Texture Bound: " << getTexUnit(i)->mCurrTexture << LL_ENDL;
@@ -2108,9 +2129,9 @@ glm::vec3 mul_mat4_vec3(const glm::mat4& mat, const glm::vec3& vec)
#if 1 // SIMD path results in strange crashes. Fall back to scalar for now.
const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3];
return glm::vec3(
- (vec[0] * mat[0][0] + vec[1] * mat[1][0] + vec[2] * mat[2][0] + mat[3][0]) / w,
- (vec[0] * mat[0][1] + vec[1] * mat[1][1] + vec[2] * mat[2][1] + mat[3][1]) / w,
- (vec[0] * mat[0][2] + vec[1] * mat[1][2] + vec[2] * mat[2][2] + mat[3][2]) / w
+ (vec[0] * mat[0][0] + vec[1] * mat[1][0] + vec[2] * mat[2][0] + mat[3][0]) / w,
+ (vec[0] * mat[0][1] + vec[1] * mat[1][1] + vec[2] * mat[2][1] + mat[3][1]) / w,
+ (vec[0] * mat[0][2] + vec[1] * mat[1][2] + vec[2] * mat[2][2] + mat[3][2]) / w
);
#else
LLVector4a x, y, z, s, t, p, q;
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 97c47bcae9..f0f9cd4364 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -421,14 +421,14 @@ public:
LLVector3 getUITranslation();
LLVector3 getUIScale();
- void flush();
+ void flush(std::string comment_ = "");
// if list is set, will store buffers in list for later use, if list isn't set, will use cache
void beginList(std::list<LLVertexBufferData> *list);
void endList();
void begin(const GLuint& mode);
- void end();
+ void end(std::string comment_ = "");
U8 getMode() const { return mMode; }
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
index 9144ce6d62..0ee47dec6d 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -833,8 +833,7 @@ void gl_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& c
{
gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
- gGL.flush();
- glLineWidth(2.5f);
+ LLRender2D::setLineWidth(2.5f);
gGL.begin(LLRender::LINES);
{
@@ -1802,12 +1801,10 @@ void LLRender2D::setLineWidth(F32 width)
// If outside the allowed range, glLineWidth fails with "invalid value".
// On Darwin, the range is [1, 1].
static GLfloat range[2]{0.0};
-#if GL_VERSION_1_2
if (range[1] == 0)
{
glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, range);
}
-#endif
width *= lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f);
glLineWidth(llclamp(width, range[0], range[1]));
}
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 0e4aa2ee7a..957c85b606 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -158,6 +158,8 @@ void LLRenderTarget::setColorAttachment(LLImageGL* img, LLGLuint use_name)
llassert(mTex.empty()); // mTex must be empty with this mode (binding target should be done via LLImageGL)
llassert(!isBoundInStack());
+ U32 target = getTarget();
+
if (mFBO == 0)
{
glGenFramebuffers(1, (GLuint*)&mFBO);
@@ -174,14 +176,14 @@ void LLRenderTarget::setColorAttachment(LLImageGL* img, LLGLuint use_name)
mTex.push_back(use_name);
- glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ glBindFramebuffer(target, mFBO);
+ glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0,
LLTexUnit::getInternalType(mUsage), use_name, 0);
stop_glerror();
check_framebuffer_status();
- glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
+ glBindFramebuffer(target, sCurFBO);
}
void LLRenderTarget::releaseColorAttachment()
@@ -194,6 +196,7 @@ void LLRenderTarget::releaseColorAttachment()
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, LLTexUnit::getInternalType(mUsage), 0, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
+ LOG_GLERROR(mName + " releaseColorAttachment()");
mTex.clear();
}
@@ -208,6 +211,8 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
return true;
}
+ U32 target = getTarget();
+
U32 offset = static_cast<U32>(mTex.size());
if( offset >= 4 )
@@ -226,12 +231,76 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
LLImageGL::generateTextures(1, &tex);
gGL.getTexUnit(0)->bindManual(mUsage, tex);
- stop_glerror();
-
+ U32 miplevel = mMipLevels;
+ U32 intformat = color_fmt;
+ U32 pixformat = GL_RGBA;
+ U32 pixtype = GL_UNSIGNED_BYTE;
{
- clear_glerror();
- LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
+ //clear_glerror();
+
+ if(color_fmt == GL_RGB10_A2)
+ {
+ pixformat = GL_RGBA;
+ pixtype = GL_UNSIGNED_BYTE;
+ }
+ else if(color_fmt == GL_R11F_G11F_B10F)
+ {
+ pixformat = GL_RGB;
+ pixtype = GL_HALF_FLOAT;
+ }
+ else if(color_fmt == GL_R8)
+ {
+ pixformat = GL_RED;
+ pixtype = GL_UNSIGNED_BYTE;
+ }
+ else if(color_fmt == GL_R16F)
+ {
+ pixformat = GL_RED;
+ pixtype = GL_HALF_FLOAT;
+ }
+ else if(color_fmt == GL_RG16F)
+ {
+ pixformat = GL_RG;
+ pixtype = GL_HALF_FLOAT;
+ }
+ else if(color_fmt == GL_RGBA16F)
+ {
+ pixformat = GL_RGBA;
+ pixtype = GL_HALF_FLOAT;
+ }
+ else if(color_fmt == GL_RGB16F)
+ {
+ pixformat = GL_RGB;
+ pixtype = GL_HALF_FLOAT;
+ }
+ else if(color_fmt == GL_RGB8)
+ {
+ pixformat = GL_RGB;
+ pixtype = GL_UNSIGNED_BYTE;
+ }
+ else if(color_fmt == GL_RGB)
+ {
+ pixformat = GL_RGB;
+ pixtype = GL_UNSIGNED_BYTE;
+ }
+ else if(color_fmt == GL_RGBA)
+ {
+ pixformat = GL_RGBA;
+ pixtype = GL_UNSIGNED_BYTE;
+ }
+ else if(color_fmt == GL_RGBA8)
+ {
+ pixformat = GL_RGBA;
+ pixtype = GL_UNSIGNED_BYTE;
+ }
+ else
+ {
+ pixformat = GL_RGBA;
+ pixtype = GL_UNSIGNED_BYTE;
+ }
+
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, pixformat, pixtype, NULL, false);
if (glGetError() != GL_NO_ERROR)
{
LL_WARNS() << "Could not allocate color buffer for render target." << LL_ENDL;
@@ -241,32 +310,30 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
sBytesAllocated += mResX*mResY*4;
- stop_glerror();
-
-
if (offset == 0)
{ //use bilinear filtering on single texture render targets that aren't multisampled
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
- stop_glerror();
+ LOG_GLERROR(mName + " setting filtering to TFO_BILINEAR");
}
else
{ //don't filter data attachments
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- stop_glerror();
+ LOG_GLERROR(mName + " setting filtering to TFO_POINT");
}
#if GL_VERSION_3_1
if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
{
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
- stop_glerror();
+ LOG_GLERROR(mName + " setting address mode to TAM_MIRROR");
+
}
else
#endif
{
// ATI doesn't support mirrored repeat for rectangular textures.
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- stop_glerror();
+ LOG_GLERROR(mName + " setting address mode to TAM_CLAMP");
}
if (mFBO)
@@ -285,7 +352,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
if (gDebugGL)
{ //bind and unbind to validate target
- bindTarget();
+ bindTarget(mName, mMode);
flush();
}
@@ -300,16 +367,15 @@ bool LLRenderTarget::allocateDepth()
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
U32 internal_type = LLTexUnit::getInternalType(mUsage);
- stop_glerror();
- clear_glerror();
- LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
+
+ LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_FLOAT, NULL, false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
sBytesAllocated += mResX*mResY*4;
if (glGetError() != GL_NO_ERROR)
{
- LL_WARNS() << "Unable to allocate depth buffer for render target." << LL_ENDL;
+ LL_WARNS() << "Unable to allocate depth buffer for render target " << mName << LL_ENDL;
return false;
}
@@ -345,6 +411,8 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
+ LOG_GLERROR(mName + " shareDepthBuffer()");
+
target.mUseDepth = true;
}
}
@@ -408,19 +476,32 @@ void LLRenderTarget::release()
LLImageGL::deleteTextures(1, &mTex[0]);
}
+ LOG_GLERROR(mName + " release()");
+
mTex.clear();
mInternalFormat.clear();
mResX = mResY = 0;
}
-void LLRenderTarget::bindTarget()
+void LLRenderTarget::bindTarget(std::string name_, U32 mode_)
{
LL_PROFILE_GPU_ZONE("bindTarget");
llassert(mFBO);
llassert(!isBoundInStack());
- glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+ //mode_ = 0;
+
+ mMode = mode_;
+ mName = name_;
+
+ U32 target = getTarget();
+
+ glBindFramebuffer(target, mFBO);
+ LOG_GLERROR(mName+" bindTarget()");
+
+ //attach();
+
sCurFBO = mFBO;
//setup multiple render targets
@@ -430,17 +511,34 @@ void LLRenderTarget::bindTarget()
GL_COLOR_ATTACHMENT3};
if (mTex.empty())
- { //no color buffer to draw to
- GLenum buffers[] = {GL_NONE};
- glDrawBuffers(0, buffers);
+ { //no color buffer to draw to
+ if(!mUseDepth) LL_WARNS() << mName << " HAS NO COLOR BUFFER AND NO DEPTH!!" << LL_ENDL;
+ glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
}
- else
+ else if(mMode == 0)
{
glDrawBuffers(static_cast<GLsizei>(mTex.size()), drawbuffers);
glReadBuffer(GL_COLOR_ATTACHMENT0);
+
+ LOG_GLERROR(mName+" read and write buffers");
+
+ }
+ else if(mMode == 1)
+ {
+ glDrawBuffers(static_cast<GLsizei>(mTex.size()), drawbuffers);
+ glReadBuffer(GL_NONE);
+ LOG_GLERROR(mName+" draw buffer");
+ }
+ else if(mMode == 2)
+ {
+ glDrawBuffer(GL_NONE);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ LOG_GLERROR(mName+" read buffer");
}
+
check_framebuffer_status();
+ LOG_GLERROR(mName+" checked status");
glViewport(0, 0, mResX, mResY);
sCurResX = mResX;
@@ -454,24 +552,22 @@ void LLRenderTarget::clear(U32 mask_in)
{
LL_PROFILE_GPU_ZONE("clear");
llassert(mFBO);
- U32 mask = GL_COLOR_BUFFER_BIT;
- if (mUseDepth)
- {
- mask |= GL_DEPTH_BUFFER_BIT;
+ U32 mask = 0;
+
+ if(!mTex.empty()) mask |= GL_COLOR_BUFFER_BIT;
+ if (mUseDepth) mask |= GL_DEPTH_BUFFER_BIT;
- }
if (mFBO)
{
check_framebuffer_status();
- stop_glerror();
glClear(mask & mask_in);
- stop_glerror();
+ LOG_GLERROR(mName + "clear()");
}
else
{
LLGLEnable scissor(GL_SCISSOR_TEST);
glScissor(0, 0, mResX, mResY);
- stop_glerror();
+ LOG_GLERROR("");
glClear(mask & mask_in);
}
}
@@ -514,29 +610,43 @@ void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilt
}
gGL.getTexUnit(channel)->setTextureFilteringOption(filter_options);
+
+ LOG_GLERROR(mName + " bindTexture()");
}
void LLRenderTarget::flush()
{
LL_PROFILE_GPU_ZONE("rt flush");
+
+ LOG_GLERROR(mName+" rt flush() A");
+
gGL.flush();
llassert(mFBO);
llassert(sCurFBO == mFBO);
llassert(sBoundTarget == this);
- if (mGenerateMipMaps == LLTexUnit::TMG_AUTO)
+ if (mGenerateMipMaps == LLTexUnit::TMG_AUTO && mMode != 2)
{
LL_PROFILE_GPU_ZONE("rt generate mipmaps");
- bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR);
+ //bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR);
+ bindTexture(0, 0, LLTexUnit::TFO_ANISOTROPIC);
glGenerateMipmap(GL_TEXTURE_2D);
+ LOG_GLERROR(mName + " glGenerateMipmap()");
}
+ LOG_GLERROR(mName + " rt flush() B");
+
+ unbind();
+}
+
+void LLRenderTarget::unbind()
+{
if (mPreviousRT)
{
// a bit hacky -- pop the RT stack back two frames and push
// the previous frame back on to play nice with the GL state machine
sBoundTarget = mPreviousRT->mPreviousRT;
- mPreviousRT->bindTarget();
+ mPreviousRT->bindTarget(mPreviousRT->mName, mPreviousRT->mMode);
}
else
{
@@ -547,9 +657,10 @@ void LLRenderTarget::flush()
sCurResX = gGLViewport[2];
sCurResY = gGLViewport[3];
glReadBuffer(GL_BACK);
- GLenum drawbuffers[] = {GL_BACK};
- glDrawBuffers(1, drawbuffers);
+ glDrawBuffer(GL_BACK);
}
+
+ LOG_GLERROR(mName + " rt unbind()");
}
bool LLRenderTarget::isComplete() const
@@ -604,3 +715,13 @@ void LLRenderTarget::swapFBORefs(LLRenderTarget& other)
std::swap(mFBO, other.mFBO);
std::swap(mTex, other.mTex);
}
+
+U32 LLRenderTarget::getTarget()
+{
+ U32 target = GL_FRAMEBUFFER;
+
+ if(mMode == 1) target = GL_DRAW_FRAMEBUFFER;
+ else if(mMode == 2) target = GL_READ_FRAMEBUFFER;
+
+ return target;
+} \ No newline at end of file
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index cd3290cf66..583d0054ac 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -33,9 +33,9 @@
#include "llrender.h"
/*
- Wrapper around OpenGL framebuffer objects for use in render-to-texture
+Wrapper around OpenGL framebuffer objects for use in render-to-texture
- SAMPLE USAGE:
+SAMPLE USAGE:
LLRenderTarget target;
@@ -126,7 +126,7 @@ public:
// If an LLRenderTarget is currently bound, stores a reference to that LLRenderTarget
// and restores previous binding on flush() (maintains a stack of Render Targets)
// Asserts that this target is not currently bound in the stack
- void bindTarget();
+ void bindTarget(std::string name_ = "nd", U32 mode_ = 0);
//clear render targer, clears depth buffer if present,
//uses scissor rect if in copy-to-texture mode
@@ -158,6 +158,7 @@ public:
// If an LLRenderTarget was bound when bindTarget was called, binds that RenderTarget for rendering (maintains RT stack)
// asserts that this target is currently bound
void flush();
+ void unbind();
//Returns TRUE if target is ready to be rendered into.
//That is, if the target has been allocated with at least
@@ -174,11 +175,15 @@ public:
static LLRenderTarget* sBoundTarget;
+ U32 mMode;
+ std::string mName;
+
protected:
U32 mResX;
U32 mResY;
std::vector<U32> mTex;
std::vector<U32> mInternalFormat;
+ std::vector<U32> mPixFormat;
U32 mFBO;
LLRenderTarget* mPreviousRT = nullptr;
@@ -188,6 +193,10 @@ protected:
U32 mMipLevels;
LLTexUnit::eTextureType mUsage;
+
+private:
+ U32 getTarget();
+
};
#endif
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 4807c12226..3bc71a7413 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -451,7 +451,7 @@ void LLShaderMgr::dumpObjectLog(GLuint ret, bool warns, const std::string& filen
LL_SHADER_LOADING_WARNS() << "Shader loading from " << fname << LL_ENDL;
LL_SHADER_LOADING_WARNS() << "\n" << log << LL_ENDL;
}
- }
+}
GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::map<std::string, std::string>* defines, S32 texture_index_channels)
{
@@ -571,7 +571,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
}
else
{
- shader_code_text[shader_code_count++] = strdup("#version 400\n");
+ shader_code_text[shader_code_count++] = strdup("#version 410\n");
}
}
else if (major_version == 3)
@@ -740,7 +740,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
//copy file into memory
enum {
- flag_write_to_out_of_extra_block_area = 0x01
+ flag_write_to_out_of_extra_block_area = 0x01
, flag_extra_block_marker_was_found = 0x02
};
@@ -756,7 +756,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
#endif
while(NULL != fgets((char *)buff, 1024, file)
- && shader_code_count < (LL_ARRAY_SIZE(shader_code_text) - LL_ARRAY_SIZE(extra_code_text)))
+ && shader_code_count < (LL_ARRAY_SIZE(shader_code_text) - LL_ARRAY_SIZE(extra_code_text)))
{
file_lines_count++;
@@ -1501,6 +1501,18 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("searchTex");
mReservedUniforms.push_back("blendTex");
+ mReservedUniforms.push_back("bloomEMap");
+ mReservedUniforms.push_back("bloomBlurredMap");
+ mReservedUniforms.push_back("bloomHorizontal");
+ mReservedUniforms.push_back("bloomBlurRadius");
+ mReservedUniforms.push_back("bloomExtractBrightness");
+ mReservedUniforms.push_back("bloomStrength");
+ mReservedUniforms.push_back("bloomExtractEmissive");
+ mReservedUniforms.push_back("bloomExtractEmissive2");
+ mReservedUniforms.push_back("bloomExtractORM");
+ mReservedUniforms.push_back("bloomExtractMetal");
+ mReservedUniforms.push_back("bloomExtractNonMetal");
+
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
std::set<std::string> dupe_check;
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 46788841a5..8b0bfc6bbe 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -341,6 +341,18 @@ public:
SMAA_SEARCH_TEX, // "searchTex"
SMAA_BLEND_TEX, // "blendTex"
+ BLOOM_EMAP, // "bloomEMap"
+ BLOOM_BMAP, // "bloomBlurredMap"
+ BLOOM_BLURH, // "bloomHorizontal"
+ BLOOM_BLUR_RADIUS, // "bloomRadius"
+ BLOOM_EXTRACT_BRIGHTNESS, // "bloomExtractBrightness"
+ BLOOM_STRENGTH, // "bloomStrength"
+ BLOOM_EXTRACT_EMISSIVE, // "bloomExtractEmissive"
+ BLOOM_EXTRACT_EMISSIVE2, // "bloomExtractEmissive2"
+ BLOOM_EXTRACT_ORM, // "bloomExtractORM"
+ BLOOM_EXTRACT_METAL, // "bloomExtractMetal"
+ BLOOM_EXTRACT_NONMETAL, // "bloomExtractNonMetal"
+
END_RESERVED_UNIFORMS
} eGLSLReservedUniforms;
// clang-format on
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index ac6db0b34f..2a0acab05a 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -345,7 +345,7 @@ public:
void allocate(GLenum type, U32 size, GLuint& name, U8*& data) override
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
- STOP_GLERROR;
+
llassert(type == GL_ARRAY_BUFFER || type == GL_ELEMENT_ARRAY_BUFFER);
llassert(name == 0); // non zero name indicates a gl name that wasn't freed
llassert(data == nullptr); // non null data indicates a buffer that wasn't freed
@@ -355,10 +355,19 @@ public:
{ //allocate a new buffer
LL_PROFILE_GPU_ZONE("vbo alloc");
- // ON OS X, we don't allocate a VBO until the last possible moment
- // in unmapBuffer
+
data = (U8*) ll_aligned_malloc_16(size);
- STOP_GLERROR;
+
+ if (type == GL_ARRAY_BUFFER)
+ {
+ glGenBuffers(1, &name);
+ LLVertexBuffer::sGLRenderBuffer = name;
+ }
+ else
+ {
+ glGenBuffers(1, &name);
+ LLVertexBuffer::sGLRenderIndices = name;
+ }
}
}
@@ -374,12 +383,12 @@ public:
}
mAllocated -= size;
- STOP_GLERROR;
+
if (name)
{
delete_buffers(1, &name);
}
- STOP_GLERROR;
+ //LOG_GLERROR("LLAppleVBOPool::free()");
}
};
@@ -783,7 +792,6 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
llassert(LLGLSLShader::sCurBoundShaderPtr != NULL);
- STOP_GLERROR;
gGL.syncMatrices();
@@ -909,10 +917,8 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
llassert(mGLBuffer == sGLRenderBuffer);
llassert(mGLIndices == sGLRenderIndices);
gGL.syncMatrices();
- STOP_GLERROR;
glDrawRangeElements(sGLMode[mode], start, end, count, mIndicesType,
(GLvoid*) (indices_offset * (size_t) mIndicesStride));
- STOP_GLERROR;
}
void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
@@ -935,9 +941,8 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
llassert(mGLIndices == sGLRenderIndices);
gGL.syncMatrices();
- STOP_GLERROR;
glDrawArrays(sGLMode[mode], first, count);
- STOP_GLERROR;
+ LOG_GLERROR("LLVertexBuffer::drawArrays()");
}
//static
@@ -970,10 +975,8 @@ void LLVertexBuffer::initClass(LLWindow* window)
//static
void LLVertexBuffer::unbind()
{
- STOP_GLERROR;
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- STOP_GLERROR;
sGLRenderBuffer = 0;
sGLRenderIndices = 0;
}
@@ -1366,7 +1369,7 @@ void LLVertexBuffer::flush_vbo(GLenum target, U32 start, U32 end, void* data, U8
// _mapBuffer to tag the buffer for flushing to GL
_mapBuffer();
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb memcpy");
- STOP_GLERROR;
+ //LOG_GLERROR("LLVertexBuffer::flush_vbo()");
// copy into mapped buffer
memcpy(dst+start, data, end-start+1);
}
@@ -1412,7 +1415,6 @@ void LLVertexBuffer::_mapBuffer()
void LLVertexBuffer::_unmapBuffer()
{
- STOP_GLERROR;
if (!mMapped)
{
return;
@@ -1428,14 +1430,14 @@ void LLVertexBuffer::_unmapBuffer()
if (gGLManager.mIsApple)
{
- STOP_GLERROR;
+ LOG_GLERROR("LLVertexBuffer::_unmapBuffer() - apple 1");
if (mMappedData)
{
- if (mGLBuffer)
+ if(mGLBuffer == 0)
{
- delete_buffers(1, &mGLBuffer);
+ LL_WARNS() << "mGLBuffer is ZERO in unmapbuffer" << LL_ENDL;
+ glGenBuffers(1, &mGLBuffer);
}
- mGLBuffer = gen_buffer();
glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
glBufferData(GL_ARRAY_BUFFER, mSize, mMappedData, GL_STATIC_DRAW);
@@ -1445,16 +1447,16 @@ void LLVertexBuffer::_unmapBuffer()
glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
}
- STOP_GLERROR;
+ LOG_GLERROR("LLVertexBuffer::_unmapBuffer() - apple 2");
if (mMappedIndexData)
{
- if (mGLIndices)
+ if (mGLIndices == 0)
{
- delete_buffers(1, &mGLIndices);
+ LL_WARNS() << "mGLIndices is ZERO in unmapbuffer" << LL_ENDL;
+ glGenBuffers(1, &mGLIndices);
}
- mGLIndices = gen_buffer();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
sGLRenderIndices = mGLIndices;
@@ -1465,7 +1467,7 @@ void LLVertexBuffer::_unmapBuffer()
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
sGLRenderIndices = mGLIndices;
}
- STOP_GLERROR;
+ LOG_GLERROR("LLVertexBuffer::_unmapBuffer() - apple 3");
}
else
{
@@ -1656,11 +1658,10 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, U32 in
// Set for rendering
void LLVertexBuffer::setBuffer()
{
- STOP_GLERROR;
if (mMapped)
{
- LL_WARNS_ONCE() << "Missing call to unmapBuffer or flushBuffers" << LL_ENDL;
+ LL_WARNS() << "Missing call to unmapBuffer or flushBuffers" << LL_ENDL;
_unmapBuffer();
}
@@ -1674,12 +1675,15 @@ void LLVertexBuffer::setBuffer()
U32 data_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask;
// this Vertex Buffer must provide all necessary attributes for currently bound shader
- llassert_msg((data_mask & mTypeMask) == data_mask,
- "Attribute mask mismatch! mTypeMask should be a superset of data_mask. data_mask: 0x"
- << std::hex << data_mask << " mTypeMask: 0x" << mTypeMask << " Missing: 0x" << (data_mask & ~mTypeMask) << std::dec);
+ llassert_msg((data_mask & mTypeMask) == data_mask, "Attribute mask mismatch! mTypeMask should be a superset of data_mask. data_mask: 0x" << std::hex << data_mask << " mTypeMask: 0x" << mTypeMask << " Missing: 0x" << (data_mask & ~mTypeMask) << std::dec);
if (sGLRenderBuffer != mGLBuffer)
{
+ if(mGLBuffer == 0)
+ {
+ LL_WARNS() << "mGLBuffer is ZERO: sGLRenderBuffer=" << sGLRenderBuffer << LL_ENDL;
+ }
+
glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
@@ -1697,14 +1701,14 @@ void LLVertexBuffer::setBuffer()
sGLRenderIndices = mGLIndices;
}
- STOP_GLERROR;
+ LOG_GLERROR("LLVertexBuffer::setBuffer()");
}
// virtual (default)
void LLVertexBuffer::setupVertexBuffer()
{
- STOP_GLERROR;
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer()");
U8* base = nullptr;
AttributeType loc;
@@ -1712,98 +1716,141 @@ void LLVertexBuffer::setupVertexBuffer()
U32 data_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask;
+ if (data_mask & MAP_VERTEX)
+ {
+ loc = TYPE_VERTEX;
+ ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
+ glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_VERTEX");
+ }
+
if (data_mask & MAP_NORMAL)
{
loc = TYPE_NORMAL;
ptr = (void*)(base + mOffsets[TYPE_NORMAL]);
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_NORMAL");
}
- if (data_mask & MAP_TEXCOORD3)
- {
- loc = TYPE_TEXCOORD3;
- ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]);
- glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr);
- }
- if (data_mask & MAP_TEXCOORD2)
+
+ if (data_mask & MAP_TEXCOORD0)
{
- loc = TYPE_TEXCOORD2;
- ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]);
- glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr);
+ loc = TYPE_TEXCOORD0;
+ //glEnableVertexAttribArray(loc);
+ ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]);
+ glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_TEXCOORD0");
}
+
if (data_mask & MAP_TEXCOORD1)
{
loc = TYPE_TEXCOORD1;
ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_TEXCOORD1");
}
- if (data_mask & MAP_TANGENT)
+
+ if (data_mask & MAP_TEXCOORD2)
{
- loc = TYPE_TANGENT;
- ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
- glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
+ loc = TYPE_TEXCOORD2;
+ ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]);
+ glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_TEXCOORD2");
}
- if (data_mask & MAP_TEXCOORD0)
+
+ if (data_mask & MAP_TEXCOORD3)
{
- loc = TYPE_TEXCOORD0;
- ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]);
- glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr);
+ loc = TYPE_TEXCOORD3;
+ ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]);
+ glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_TEXCOORD3");
}
+
if (data_mask & MAP_COLOR)
{
loc = TYPE_COLOR;
//bind emissive instead of color pointer if emissive is present
ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_COLOR");
}
+
if (data_mask & MAP_EMISSIVE)
{
loc = TYPE_EMISSIVE;
ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_EMISSIVE");
+
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;
glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_COLOR");
}
}
+
+ if (data_mask & MAP_TANGENT)
+ {
+ loc = TYPE_TANGENT;
+ ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
+ glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_TANGENT");
+ }
+
if (data_mask & MAP_WEIGHT)
{
loc = TYPE_WEIGHT;
ptr = (void*)(base + mOffsets[TYPE_WEIGHT]);
glVertexAttribPointer(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_WEIGHT");
}
+
if (data_mask & MAP_WEIGHT4)
{
loc = TYPE_WEIGHT4;
ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]);
glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_WEIGHT4");
}
- if (data_mask & MAP_JOINT)
- {
- loc = TYPE_JOINT;
- ptr = (void*)(base + mOffsets[TYPE_JOINT]);
- glVertexAttribIPointer(loc, 4, GL_UNSIGNED_SHORT, LLVertexBuffer::sTypeSize[TYPE_JOINT], ptr);
- }
+
if (data_mask & MAP_CLOTHWEIGHT)
{
loc = TYPE_CLOTHWEIGHT;
ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
glVertexAttribPointer(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_CLOTHWEIGHT");
}
+
+ if (data_mask & MAP_JOINT)
+ {
+ loc = TYPE_JOINT;
+ ptr = (void*)(base + mOffsets[TYPE_JOINT]);
+ glVertexAttribIPointer(loc, 4, GL_UNSIGNED_SHORT, LLVertexBuffer::sTypeSize[TYPE_JOINT], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_JOINT");
+ }
+
if (data_mask & MAP_TEXTURE_INDEX)
{
loc = TYPE_TEXTURE_INDEX;
ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12);
glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+
+ LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_TEXTURE_INDEX");
}
- if (data_mask & MAP_VERTEX)
- {
- loc = TYPE_VERTEX;
- ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
- glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
- }
- STOP_GLERROR;
}
void LLVertexBuffer::setPositionData(const LLVector4a* data)