From 51bb3c15c8ac6c85ed1a7e8526ba6b60794ac29e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 19 May 2011 20:38:39 -0500 Subject: SH-469 WIP -- get rid of LLMultiSampleBuffer and use GL_ARB_texture_multisample instead. --- indra/llrender/llgl.cpp | 49 ++++- indra/llrender/llgl.h | 8 +- indra/llrender/llglheaders.h | 10 + indra/llrender/llglslshader.cpp | 3 +- indra/llrender/llimagegl.cpp | 2 +- indra/llrender/llrender.cpp | 25 ++- indra/llrender/llrender.h | 1 + indra/llrender/llrendertarget.cpp | 394 ++++++++++---------------------------- indra/llrender/llrendertarget.h | 26 +-- 9 files changed, 186 insertions(+), 332 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index f29ee0e57e..8d000d6fe3 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -178,6 +178,12 @@ PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = NULL; PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample = NULL; PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = NULL; +//GL_ARB_texture_multisample +PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; +PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; +PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; +PFNGLSAMPLEMASKIPROC glSampleMaski; + // GL_EXT_blend_func_separate PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL; @@ -321,6 +327,7 @@ LLGLManager::LLGLManager() : mHasMipMapGeneration(FALSE), mHasCompressedTextures(FALSE), mHasFramebufferObject(FALSE), + mMaxSamples(0), mHasBlendFuncSeparate(FALSE), mHasVertexBufferObject(FALSE), @@ -333,6 +340,11 @@ LLGLManager::LLGLManager() : mHasPointParameters(FALSE), mHasDrawBuffers(FALSE), mHasTextureRectangle(FALSE), + mHasTextureMultisample(FALSE), + mMaxSampleMaskWords(0), + mMaxColorTextureSamples(0), + mMaxDepthTextureSamples(0), + mMaxIntegerSamples(0), mHasAnisotropic(FALSE), mHasARBEnvCombine(FALSE), @@ -534,6 +546,19 @@ bool LLGLManager::initGL() return false; } + if (mHasTextureMultisample) + { + glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples); + glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples); + glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples); + glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords); + } + + if (mHasFramebufferObject) + { + glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); + } + setToDebugGPU(); initGLStates(); @@ -734,6 +759,7 @@ void LLGLManager::initExtensions() mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts); mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts); mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts); + mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts); #if !LL_DARWIN mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts); #endif @@ -943,6 +969,13 @@ void LLGLManager::initExtensions() { glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT"); } + if (mHasTextureRectangle) + { + glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage2DMultisample"); + glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample"); + glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv"); + glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski"); + } #if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS // This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements"); @@ -1374,7 +1407,8 @@ void LLGLState::checkTextureChannels(const std::string& msg) "GL_TEXTURE_GEN_T", "GL_TEXTURE_GEN_Q", "GL_TEXTURE_GEN_R", - "GL_TEXTURE_RECTANGLE_ARB" + "GL_TEXTURE_RECTANGLE_ARB", + "GL_TEXTURE_2D_MULTISAMPLE" }; static GLint value[] = @@ -1387,7 +1421,8 @@ void LLGLState::checkTextureChannels(const std::string& msg) GL_TEXTURE_GEN_T, GL_TEXTURE_GEN_Q, GL_TEXTURE_GEN_R, - GL_TEXTURE_RECTANGLE_ARB + GL_TEXTURE_RECTANGLE_ARB, + GL_TEXTURE_2D_MULTISAMPLE }; GLint stackDepth = 0; @@ -1429,9 +1464,17 @@ void LLGLState::checkTextureChannels(const std::string& msg) } + S32 num_texture_types = 8; + for (S32 j = (i == 0 ? 1 : 0); - j < (gGLManager.mHasTextureRectangle ? 9 : 8); j++) + j < 9; j++) { + if (j == 8 && !gGLManager.mHasTextureRectangle || + j == 9 && !gGLManager.mHasTextureMultisample) + { + continue; + } + if (glIsEnabled(value[j])) { error = TRUE; diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 3d002fd8c4..7484196db5 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -83,8 +83,9 @@ public: BOOL mHasMipMapGeneration; BOOL mHasCompressedTextures; BOOL mHasFramebufferObject; + S32 mMaxSamples; BOOL mHasBlendFuncSeparate; - + // ARB Extensions BOOL mHasVertexBufferObject; BOOL mHasPBuffer; @@ -97,6 +98,11 @@ public: BOOL mHasDrawBuffers; BOOL mHasDepthClamp; BOOL mHasTextureRectangle; + BOOL mHasTextureMultisample; + S32 mMaxSampleMaskWords; + S32 mMaxColorTextureSamples; + S32 mMaxDepthTextureSamples; + S32 mMaxIntegerSamples; // Other extensions. BOOL mHasAnisotropic; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index d8140a124d..825d304d35 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -474,6 +474,11 @@ extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer; //GL_ARB_draw_buffers extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; +//GL_ARB_texture_multisample +extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; +extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; +extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; +extern PFNGLSAMPLEMASKIPROC glSampleMaski; #elif LL_WINDOWS //---------------------------------------------------------------------------- @@ -673,6 +678,11 @@ extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer; //GL_ARB_draw_buffers extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; +//GL_ARB_texture_multisample +extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; +extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; +extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; +extern PFNGLSAMPLEMASKIPROC glSampleMaski; #elif LL_DARWIN //---------------------------------------------------------------------------- diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 257bcd9380..2e7147a3b4 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -293,7 +293,8 @@ void LLGLSLShader::mapUniform(GLint index, const vector * uniforms) GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) { - if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) + if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB || + type == GL_SAMPLER_2D_MULTISAMPLE) { //this here is a texture glUniform1iARB(location, mActiveTextureChannels); LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index d408077c68..30b66ae542 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1417,7 +1417,7 @@ void LLImageGL::deleteDeadTextures() { if (sCurrentBoundTextures[i] == tex) { - gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); stop_glerror(); } } diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 49e10c4790..d5eb3979c3 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -53,7 +53,8 @@ static GLenum sGLTextureType[] = { GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_ARB, - GL_TEXTURE_CUBE_MAP_ARB + GL_TEXTURE_CUBE_MAP_ARB, + GL_TEXTURE_2D_MULTISAMPLE }; static GLint sGLAddressMode[] = @@ -121,12 +122,18 @@ void LLTexUnit::refreshState(void) glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); if (mCurrTexType != TT_NONE) { - glEnable(sGLTextureType[mCurrTexType]); + if (mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE) + { + glEnable(sGLTextureType[mCurrTexType]); + } glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture); } else { - glDisable(GL_TEXTURE_2D); + if (mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE) + { + glDisable(GL_TEXTURE_2D); + } glBindTexture(GL_TEXTURE_2D, 0); } @@ -167,7 +174,10 @@ void LLTexUnit::enable(eTextureType type) mCurrTexType = type; gGL.flush(); - glEnable(sGLTextureType[type]); + if (type != LLTexUnit::TT_MULTISAMPLE_TEXTURE) + { + glEnable(sGLTextureType[type]); + } } } @@ -180,7 +190,10 @@ void LLTexUnit::disable(void) activate(); unbind(mCurrTexType); gGL.flush(); - glDisable(sGLTextureType[mCurrTexType]); + if (mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE) + { + glDisable(sGLTextureType[mCurrTexType]); + } mCurrTexType = TT_NONE; } } @@ -399,7 +412,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(); diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 7ba14f7b40..41e7b35341 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -57,6 +57,7 @@ public: 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 TT_NONE // No texture type is currently enabled } eTextureType; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index cd2556d435..53c85e6c64 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -44,6 +44,7 @@ void check_framebuffer_status() case GL_FRAMEBUFFER_COMPLETE: break; default: + llwarns << "Bad framebuffer status: " << std::hex << status << llendl; ll_fail("check_framebuffer_status failed"); break; } @@ -62,8 +63,7 @@ LLRenderTarget::LLRenderTarget() : mUseDepth(false), mRenderDepth(false), mUsage(LLTexUnit::TT_TEXTURE), - mSamples(0), - mSampleBuffer(NULL) + mSamples(0) { } @@ -72,13 +72,7 @@ LLRenderTarget::~LLRenderTarget() release(); } - -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) +void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples) { stop_glerror(); mResX = resx; @@ -87,6 +81,21 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo mStencil = stencil; mUsage = usage; mUseDepth = depth; + mSamples = samples; + + mSamples = llmin(mSamples, (U32) gGLManager.mMaxColorTextureSamples); + + if (mSamples > 0 && gGLManager.mHasTextureMultisample) + { + mSamples = llmin(mSamples, (U32) gGLManager.mMaxColorTextureSamples); + mUsage = LLTexUnit::TT_MULTISAMPLE_TEXTURE; + //no support for multisampled stencil targets yet + mStencil = false; + } + else + { + mSamples = 0; + } release(); @@ -145,29 +154,47 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt) stop_glerror(); - LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - stop_glerror(); - - if (offset == 0) + if (mSamples > 0) { - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, color_fmt, mResX, mResY, GL_TRUE); } 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); + LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } - else - { - // ATI doesn't support mirrored repeat for rectangular textures. - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + + stop_glerror(); + + if (mSamples == 0) + { + 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(); glBindFramebuffer(GL_FRAMEBUFFER, mFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset, LLTexUnit::getInternalType(mUsage), tex, 0); @@ -196,9 +223,16 @@ void LLRenderTarget::allocateDepth() { LLImageGL::generateTextures(1, &mDepth); gGL.getTexUnit(0)->bindManual(mUsage, mDepth); - U32 internal_type = LLTexUnit::getInternalType(mUsage); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + if (mSamples == 0) + { + U32 internal_type = LLTexUnit::getInternalType(mUsage); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + } + else + { + glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, GL_DEPTH_COMPONENT32, mResX, mResY, GL_TRUE); + } } } @@ -288,7 +322,6 @@ void LLRenderTarget::release() mTex.clear(); } - mSampleBuffer = NULL; sBoundTarget = NULL; } @@ -297,34 +330,27 @@ void LLRenderTarget::bindTarget() if (mFBO) { stop_glerror(); - if (mSampleBuffer) - { - mSampleBuffer->bindTarget(this); - stop_glerror(); + + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + stop_glerror(); + if (gGLManager.mHasDrawBuffers) + { //setup multiple render targets + GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3}; + glDrawBuffersARB(mTex.size(), drawbuffers); } - else - { - glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - stop_glerror(); - if (gGLManager.mHasDrawBuffers) - { //setup multiple render targets - GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, - GL_COLOR_ATTACHMENT1, - GL_COLOR_ATTACHMENT2, - GL_COLOR_ATTACHMENT3}; - glDrawBuffersARB(mTex.size(), drawbuffers); - } - if (mTex.empty()) - { //no color buffer to draw to - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); - } + if (mTex.empty()) + { //no color buffer to draw to + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + } - check_framebuffer_status(); + check_framebuffer_status(); - stop_glerror(); - } + stop_glerror(); } glViewport(0, 0, mResX, mResY); @@ -406,50 +432,8 @@ void LLRenderTarget::flush(bool fetch_depth) else { stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - stop_glerror(); - - if (mSampleBuffer) - { - LLGLEnable multisample(GL_MULTISAMPLE); - stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - stop_glerror(); - check_framebuffer_status(); - glBindFramebuffer(GL_READ_FRAMEBUFFER, mSampleBuffer->mFBO); - check_framebuffer_status(); - - stop_glerror(); - glBlitFramebuffer(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) - { - for (U32 i = 1; i < mTex.size(); ++i) - { - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - LLTexUnit::getInternalType(mUsage), mTex[i], 0); - stop_glerror(); - glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mSampleBuffer->mTex[i]); - stop_glerror(); - glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT, GL_NEAREST); - stop_glerror(); - } - - for (U32 i = 0; i < mTex.size(); ++i) - { - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, - LLTexUnit::getInternalType(mUsage), mTex[i], 0); - stop_glerror(); - glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_RENDERBUFFER, mSampleBuffer->mTex[i]); - stop_glerror(); - } - } - } - - glBindFramebuffer(GL_FRAMEBUFFER, 0); } } @@ -466,37 +450,31 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl; } - if (mSampleBuffer) + + if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil) { - mSampleBuffer->copyContents(source, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + stop_glerror(); + + glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO); + gGL.getTexUnit(0)->bind(this, true); + stop_glerror(); + glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); + stop_glerror(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + stop_glerror(); } else { - if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil) - { - stop_glerror(); - - glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO); - gGL.getTexUnit(0)->bind(this, true); - stop_glerror(); - glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); - stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - stop_glerror(); - } - else - { - glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO); - stop_glerror(); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO); - stop_glerror(); - check_framebuffer_status(); - stop_glerror(); - glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - stop_glerror(); - } + glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO); + stop_glerror(); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO); + stop_glerror(); + check_framebuffer_status(); + stop_glerror(); + glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + stop_glerror(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + stop_glerror(); } } @@ -539,179 +517,3 @@ void LLRenderTarget::getViewport(S32* viewport) viewport[3] = mResY; } -//================================================== -// LLMultisampleBuffer implementation -//================================================== -LLMultisampleBuffer::LLMultisampleBuffer() -{ - -} - -LLMultisampleBuffer::~LLMultisampleBuffer() -{ - release(); -} - -void LLMultisampleBuffer::release() -{ - if (mFBO) - { - glDeleteFramebuffers(1, (GLuint *) &mFBO); - mFBO = 0; - } - - if (mTex.size() > 0) - { - glDeleteRenderbuffers(mTex.size(), (GLuint *) &mTex[0]); - mTex.clear(); - } - - if (mDepth) - { - glDeleteRenderbuffers(1, (GLuint *) &mDepth); - mDepth = 0; - } -} - -void LLMultisampleBuffer::bindTarget() -{ - bindTarget(this); -} - -void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref) -{ - if (!ref) - { - ref = this; - } - - glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - if (gGLManager.mHasDrawBuffers) - { //setup multiple render targets - GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, - GL_COLOR_ATTACHMENT1, - GL_COLOR_ATTACHMENT2, - GL_COLOR_ATTACHMENT3}; - glDrawBuffersARB(ref->mTex.size(), drawbuffers); - } - - check_framebuffer_status(); - - glViewport(0, 0, mResX, mResY); - - sBoundTarget = this; -} - -void 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); -} - -void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples ) -{ - stop_glerror(); - mResX = resx; - mResY = resy; - - mUsage = usage; - mUseDepth = depth; - mStencil = stencil; - - release(); - - mSamples = samples; - - if (mSamples <= 1) - { - llerrs << "Cannot create a multisample buffer with less than 2 samples." << llendl; - } - - stop_glerror(); - - if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) - { - - if (depth) - { - stop_glerror(); - allocateDepth(); - stop_glerror(); - } - - glGenFramebuffers(1, (GLuint *) &mFBO); - - glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - - if (mDepth) - { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth); - if (mStencil) - { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth); - } - } - - stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - stop_glerror(); - } - - addColorAttachment(color_fmt); -} - -void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) -{ - if (color_fmt == 0) - { - return; - } - - U32 offset = mTex.size(); - if (offset >= 4 || - (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) - { - llerrs << "Too many color attachments!" << llendl; - } - - U32 tex; - glGenRenderbuffers(1, &tex); - - glBindRenderbuffer(GL_RENDERBUFFER, tex); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, color_fmt, mResX, mResY); - stop_glerror(); - - if (mFBO) - { - glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset, GL_RENDERBUFFER, tex); - stop_glerror(); - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - switch (status) - { - case GL_FRAMEBUFFER_COMPLETE: - break; - default: - llerrs << "WTF? " << std::hex << status << llendl; - break; - } - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - - mTex.push_back(tex); -} - -void LLMultisampleBuffer::allocateDepth() -{ - glGenRenderbuffers(1, (GLuint* ) &mDepth); - glBindRenderbuffer(GL_RENDERBUFFER, mDepth); - if (mStencil) - { - glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH24_STENCIL8, mResX, mResY); - } - else - { - glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH_COMPONENT16, mResX, mResY); - } -} - diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 12dd1c8b90..094b58b562 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -71,10 +71,7 @@ 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); - - //provide this render target with a multisample resource. - void setSampleBuffer(LLMultisampleBuffer* buffer); + void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0); //add color buffer attachment //limit of 4 color attachments per render target @@ -141,7 +138,6 @@ public: static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; } protected: - friend class LLMultisampleBuffer; U32 mResX; U32 mResY; std::vector mTex; @@ -152,26 +148,8 @@ protected: bool mRenderDepth; LLTexUnit::eTextureType mUsage; U32 mSamples; - LLMultisampleBuffer* mSampleBuffer; - - static LLRenderTarget* sBoundTarget; -}; - -class LLMultisampleBuffer : public LLRenderTarget -{ -public: - LLMultisampleBuffer(); - virtual ~LLMultisampleBuffer(); - - virtual void release(); - - 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(); + static LLRenderTarget* sBoundTarget; }; #endif //!LL_MESA_HEADLESS -- cgit v1.2.3