diff options
Diffstat (limited to 'indra/llrender')
| -rw-r--r-- | indra/llrender/llcubemaparray.cpp | 3 | ||||
| -rw-r--r-- | indra/llrender/llgl.cpp | 14 | ||||
| -rw-r--r-- | indra/llrender/llgl.h | 13 | ||||
| -rw-r--r-- | indra/llrender/llimagegl.cpp | 7 | ||||
| -rw-r--r-- | indra/llrender/llrender.cpp | 117 | ||||
| -rw-r--r-- | indra/llrender/llrender.h | 4 | ||||
| -rw-r--r-- | indra/llrender/llrender2dutils.cpp | 5 | ||||
| -rw-r--r-- | indra/llrender/llrendertarget.cpp | 197 | ||||
| -rw-r--r-- | indra/llrender/llrendertarget.h | 15 | ||||
| -rw-r--r-- | indra/llrender/llshadermgr.cpp | 20 | ||||
| -rw-r--r-- | indra/llrender/llshadermgr.h | 12 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 171 | 
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) | 
