Replaced some opengl fixed functions with shaders. Temporary ShyotlUseLegacyRenderPath setting to debug if this change actually improves framerate at all (setting not tied to callbacks. Have to toggle shaders to have stuff pick up the setting change)

This commit is contained in:
Shyotl
2011-08-10 03:53:49 -05:00
parent 896b7146e7
commit ca328aec72
41 changed files with 1037 additions and 273 deletions

View File

@@ -55,6 +55,14 @@ using std::make_pair;
using std::string;
GLhandleARB LLGLSLShader::sCurBoundShader = 0;
bool LLGLSLShader::sNoFixedFunction = false;
//UI shader -- declared here so llui_libtest will link properly
//Singu note: Not using llui_libtest... and LLViewerShaderMgr is a part of newview. So,
// these are declared in newview/llviewershadermanager.cpp just like every other shader.
//LLGLSLShader gUIProgram(LLViewerShaderMgr::SHADER_INTERFACE);
//LLGLSLShader gSolidColorProgram(LLViewerShaderMgr::SHADER_INTERFACE);
BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
{
return v1 != v2;
@@ -395,6 +403,7 @@ BOOL LLGLSLShader::link(BOOL suppress_errors)
void LLGLSLShader::bind()
{
gGL.flush();
if (gGLManager.mHasShaderObjects)
{
glUseProgramObjectARB(mProgramObject);
@@ -409,6 +418,7 @@ void LLGLSLShader::bind()
void LLGLSLShader::unbind()
{
gGL.flush();
if (gGLManager.mHasShaderObjects)
{
stop_glerror();

View File

@@ -75,6 +75,7 @@ public:
LLGLSLShader(S32 shader_class);
static GLhandleARB sCurBoundShader;
static bool sNoFixedFunction;
void unload();
BOOL createShader(std::vector<std::string> * attributes,
@@ -150,4 +151,9 @@ public:
std::string mName;
};
//UI shader (declared here so llui_libtest will link properly)
extern LLGLSLShader gUIProgram;
//output vec4(color.rgb,color.a*tex0[tc0].a)
extern LLGLSLShader gSolidColorProgram;
#endif

View File

@@ -1400,6 +1400,8 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
void LLImageGL::deleteDeadTextures()
{
bool reset = false;
while (!sDeadTextureList.empty())
{
GLuint tex = sDeadTextureList.front();
@@ -1412,12 +1414,22 @@ void LLImageGL::deleteDeadTextures()
{
tex_unit->unbind(tex_unit->getCurrType());
stop_glerror();
if (i > 0)
{
reset = true;
}
}
}
glDeleteTextures(1, &tex);
stop_glerror();
}
if (reset)
{
gGL.getTexUnit(0)->activate();
}
}
void LLImageGL::destroyGLTexture()

View File

@@ -36,6 +36,7 @@
#include "llvertexbuffer.h"
#include "llcubemap.h"
#include "llglslshader.h"
#include "llimagegl.h"
#include "llrendertarget.h"
#include "lltexture.h"
@@ -49,6 +50,7 @@ F64 gGLLastProjection[16];
F64 gGLProjection[16];
S32 gGLViewport[4];
U32 LLTexUnit::sWhiteTexture = 0;
static const U32 LL_NUM_TEXTURE_LAYERS = 32;
static const U32 LL_NUM_LIGHT_UNITS = 8;
@@ -58,6 +60,7 @@ static GLenum sGLTextureType[] =
GL_TEXTURE_2D,
GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_CUBE_MAP_ARB
//,GL_TEXTURE_2D_MULTISAMPLE Don't use.
};
static GLint sGLAddressMode[] =
@@ -128,7 +131,8 @@ void LLTexUnit::refreshState(void)
// Per apple spec, don't call glEnable/glDisable when index exceeds max texture units
// http://www.mailinglistarchive.com/html/mac-opengl@lists.apple.com/2008-07/msg00653.html
//
bool enableDisable = (mIndex < gGLManager.mNumTextureUnits);
bool enableDisable = !LLGLSLShader::sNoFixedFunction &&
(mIndex < gGLManager.mNumTextureUnits) /*&& mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE*/;
if (mCurrTexType != TT_NONE)
{
@@ -184,8 +188,11 @@ void LLTexUnit::enable(eTextureType type)
disable(); // Force a disable of a previous texture type if it's enabled.
}
mCurrTexType = type;
gGL.flush();
if (mIndex < gGLManager.mNumTextureUnits)
if (!LLGLSLShader::sNoFixedFunction &&
//type != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&
mIndex < gGLManager.mNumTextureUnits)
{
glEnable(sGLTextureType[type]);
}
@@ -201,7 +208,9 @@ void LLTexUnit::disable(void)
activate();
unbind(mCurrTexType);
gGL.flush();
if (mIndex < gGLManager.mNumTextureUnits)
if (!LLGLSLShader::sNoFixedFunction &&
//mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&
mIndex < gGLManager.mNumTextureUnits)
{
glDisable(sGLTextureType[mCurrTexType]);
}
@@ -405,7 +414,15 @@ void LLTexUnit::unbind(eTextureType type)
activate();
mCurrTexture = 0;
glBindTexture(sGLTextureType[type], 0);
if (LLGLSLShader::sNoFixedFunction && type == LLTexUnit::TT_TEXTURE)
{
glBindTexture(sGLTextureType[type], sWhiteTexture);
}
else
{
glBindTexture(sGLTextureType[type], 0);
}
stop_glerror();
}
}
@@ -427,7 +444,7 @@ void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option)
{
if (mIndex < 0 || mCurrTexture == 0) return;
if (mIndex < 0 || mCurrTexture == 0 /*|| mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE*/) return;
gGL.flush();
@@ -475,6 +492,11 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio
void LLTexUnit::setTextureBlendType(eTextureBlendType type)
{
if (LLGLSLShader::sNoFixedFunction)
{ //texture blend type means nothing when using shaders
return;
}
if (mIndex < 0) return;
// Do nothing if it's already correctly set.
@@ -595,6 +617,11 @@ GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha)
void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha)
{
if (LLGLSLShader::sNoFixedFunction)
{ //register combiners do nothing when not using fixed function
return;
}
if (mIndex < 0) return;
activate();

View File

@@ -58,11 +58,13 @@ class LLTexUnit
{
friend class LLRender;
public:
static U32 sWhiteTexture;
typedef enum
{
TT_TEXTURE = 0, // Standard 2D Texture
TT_RECT_TEXTURE, // Non power of 2 texture
TT_CUBE_MAP, // 6-sided cube map texture
//TT_MULTISAMPLE_TEXTURE, // see GL_ARB_texture_multisample Do not use
TT_NONE // No texture type is currently enabled
} eTextureType;

View File

@@ -44,13 +44,14 @@ void check_framebuffer_status()
{
if (gDebugGL)
{
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
GLenum status = glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
switch (status)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
break;
default:
llerrs <<"check_framebuffer_status failed" << llendl;
llwarns << "check_framebuffer_status failed -- " << std::hex << status << llendl;
ll_fail("check_framebuffer_status failed");
break;
}
}
@@ -84,9 +85,12 @@ void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer)
mSampleBuffer = buffer;
}
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo)
bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo)
{
stop_glerror();
release();
stop_glerror();
mResX = resx;
mResY = resy;
@@ -94,15 +98,16 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
mUsage = usage;
mUseDepth = depth;
release();
if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
{
if (depth)
{
stop_glerror();
allocateDepth();
stop_glerror();
if (!allocateDepth())
{
llwarns << "Failed to allocate depth buffer for render target." << llendl;
return false;
}
}
glGenFramebuffersEXT(1, (GLuint *) &mFBO);
@@ -128,14 +133,14 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
stop_glerror();
}
addColorAttachment(color_fmt);
return addColorAttachment(color_fmt);
}
void LLRenderTarget::addColorAttachment(U32 color_fmt)
bool LLRenderTarget::addColorAttachment(U32 color_fmt)
{
if (color_fmt == 0)
{
return;
return true;
}
U32 offset = mTex.size();
@@ -151,29 +156,46 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)
stop_glerror();
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
{
clear_glerror();
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
if (glGetError() != GL_NO_ERROR)
{
llwarns << "Could not allocate color buffer for render target." << llendl;
return false;
}
}
stop_glerror();
if (offset == 0)
{
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
}
else
{ //don't filter data attachments
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
{
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
}
else
{
// ATI doesn't support mirrored repeat for rectangular textures.
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
if (offset == 0)
{ //use bilinear filtering on single texture render targets that aren't multisampled
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
stop_glerror();
}
else
{ //don't filter data attachments
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
stop_glerror();
}
if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
{
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
stop_glerror();
}
else
{
// ATI doesn't support mirrored repeat for rectangular textures.
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
stop_glerror();
}
}
if (mFBO)
{
stop_glerror();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+offset,
LLTexUnit::getInternalType(mUsage), tex, 0);
@@ -186,15 +208,24 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)
mTex.push_back(tex);
if (gDebugGL)
{ //bind and unbind to validate target
bindTarget();
flush();
}
return true;
}
void LLRenderTarget::allocateDepth()
bool LLRenderTarget::allocateDepth()
{
if (mStencil)
{
//use render buffers where stencil buffers are in play
glGenRenderbuffersEXT(1, (GLuint *) &mDepth);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepth);
stop_glerror();
clear_glerror();
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, mResX, mResY);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
}
@@ -204,8 +235,18 @@ void LLRenderTarget::allocateDepth()
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
U32 internal_type = LLTexUnit::getInternalType(mUsage);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
stop_glerror();
clear_glerror();
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32_ARB, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
}
if (glGetError() != GL_NO_ERROR)
{
llwarns << "Unable to allocate depth buffer for render target." << llendl;
return false;
}
return true;
}
void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
@@ -244,9 +285,10 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
stop_glerror();
}
check_framebuffer_status();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
target.mUseDepth = TRUE;
target.mUseDepth = true;
}
}
@@ -294,6 +336,8 @@ void LLRenderTarget::release()
mTex.clear();
}
mResX = mResY = 0;
mSampleBuffer = NULL;
sBoundTarget = NULL;
}
@@ -434,7 +478,9 @@ void LLRenderTarget::flush(bool fetch_depth)
glBlitFramebufferEXT(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
else
{
glBlitFramebufferEXT(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
stop_glerror();
if (mTex.size() > 1)
@@ -459,9 +505,8 @@ void LLRenderTarget::flush(bool fetch_depth)
stop_glerror();
}
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
}
@@ -489,6 +534,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
stop_glerror();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, source.mFBO);
check_framebuffer_status();
gGL.getTexUnit(0)->bind(this, true);
stop_glerror();
glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1);
@@ -512,6 +558,10 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
if(mask)
glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
stop_glerror();
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
stop_glerror();
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
stop_glerror();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
stop_glerror();
}
@@ -626,14 +676,16 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
sBoundTarget = this;
}
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo )
bool LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo )
{
allocate(resx,resy,color_fmt,depth,stencil,usage,use_fbo,2);
return allocate(resx,resy,color_fmt,depth,stencil,usage,use_fbo,2);
}
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples )
bool LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples )
{
release();
stop_glerror();
mResX = resx;
mResY = resy;
@@ -641,11 +693,10 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth
mUseDepth = depth;
mStencil = stencil;
release();
if (!gGLManager.mHasFramebufferMultisample)
{
llerrs << "Attempting to allocate unsupported render target type!" << llendl;
return false;
}
mSamples = samples;
@@ -653,6 +704,7 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth
if (mSamples <= 1)
{
llerrs << "Cannot create a multisample buffer with less than 2 samples." << llendl;
return false;
}
stop_glerror();
@@ -663,14 +715,14 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth
if (depth)
{
stop_glerror();
allocateDepth();
if(!allocateDepth())
return false;
stop_glerror();
}
glGenFramebuffersEXT(1, (GLuint *) &mFBO);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
stop_glerror();
clear_glerror();
if (mDepth)
{
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);
@@ -678,6 +730,7 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth
{
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);
}
check_framebuffer_status();
}
stop_glerror();
@@ -685,14 +738,14 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth
stop_glerror();
}
addColorAttachment(color_fmt);
return addColorAttachment(color_fmt);
}
void LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
bool LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
{
if (color_fmt == 0)
{
return;
return true;
}
U32 offset = mTex.size();
@@ -704,36 +757,33 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
U32 tex;
glGenRenderbuffersEXT(1, &tex);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, tex);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, color_fmt, mResX, mResY);
stop_glerror();
clear_glerror();
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, color_fmt, mResX, mResY);
if (glGetError() != GL_NO_ERROR)
{
llwarns << "Unable to allocate color buffer for multisample render target." << llendl;
return false;
}
if (mFBO)
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+offset, GL_RENDERBUFFER_EXT, tex);
stop_glerror();
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
switch (status)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
break;
default:
llerrs << "WTF? " << std::hex << status << llendl;
break;
}
check_framebuffer_status();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
mTex.push_back(tex);
return true;
}
void LLMultisampleBuffer::allocateDepth()
bool LLMultisampleBuffer::allocateDepth()
{
glGenRenderbuffersEXT(1, (GLuint* ) &mDepth);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepth);
stop_glerror();
clear_glerror();
if (mStencil)
{
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, GL_DEPTH24_STENCIL8_EXT, mResX, mResY);
@@ -742,5 +792,11 @@ void LLMultisampleBuffer::allocateDepth()
{
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, GL_DEPTH_COMPONENT16_ARB, mResX, mResY);
}
if (glGetError() != GL_NO_ERROR)
{
llwarns << "Unable to allocate depth buffer for multisample render target." << llendl;
return false;
}
return true;
}

View File

@@ -77,17 +77,17 @@ public:
//allocate resources for rendering
//must be called before use
//multiple calls will release previously allocated resources
void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = FALSE);
bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = FALSE);
//provide this render target with a multisample resource.
void setSampleBuffer(LLMultisampleBuffer* buffer);
//add color buffer attachment
//limit of 4 color attachments per render target
virtual void addColorAttachment(U32 color_fmt);
virtual bool addColorAttachment(U32 color_fmt);
//allocate a depth texture
virtual void allocateDepth();
virtual bool allocateDepth();
//share depth buffer with provided render target
virtual void shareDepthBuffer(LLRenderTarget& target);
@@ -174,10 +174,10 @@ public:
virtual void bindTarget();
void bindTarget(LLRenderTarget* ref);
virtual void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo);
void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples);
virtual void addColorAttachment(U32 color_fmt);
virtual void allocateDepth();
virtual bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo);
bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples);
virtual bool addColorAttachment(U32 color_fmt);
virtual bool allocateDepth();
};
#endif //!LL_MESA_HEADLESS