void LLRenderTarget::flush(bool fetch_depth) { gGL.flush(); if (!mFBO) { gGL.getTexUnit(0)->bind(this); glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, 0, 0, 0, 0, mResX, mResY); if (fetch_depth) { if (!mDepth) { allocateDepth(); } gGL.getTexUnit(0)->bind(this); glCopyTexImage2D(LLTexUnit::getInternalType(mUsage), 0, GL_DEPTH24_STENCIL8, 0, 0, mResX, mResY, 0); } gGL.getTexUnit(0)->disable(); } else { stop_glerror(); glBindFramebuffer(GL_FRAMEBUFFER, 0); stop_glerror(); } }
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(); if (!gGLManager.mHasFramebufferMultisample) { llerrs << "Attempting to allocate unsupported render target type!" << llendl; } 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(); } glGenFramebuffersEXT(1, (GLuint *) &mFBO); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); if (mDepth) { glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth); if (mStencil) { glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth); } } stop_glerror(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); stop_glerror(); } addColorAttachment(color_fmt); }
bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples) { stop_glerror(); release(); stop_glerror(); mResX = resx; mResY = resy; mStencil = stencil; mUsage = usage; mUseDepth = depth; if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) { if (depth) { if (!allocateDepth()) { llwarns << "Failed to allocate depth buffer for render target." << llendl; return false; } } glGenFramebuffers(1, (GLuint *) &mFBO); if (mDepth) { glBindFramebuffer(GL_FRAMEBUFFER, mFBO); if (mStencil) { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth); stop_glerror(); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth); stop_glerror(); } else { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0); stop_glerror(); } glBindFramebuffer(GL_FRAMEBUFFER, 0); } stop_glerror(); } return addColorAttachment(color_fmt); }
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo) { stop_glerror(); mResX = resx; mResY = resy; mStencil = stencil; mUsage = usage; mUseDepth = depth; release(); if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) { if (depth) { stop_glerror(); allocateDepth(); stop_glerror(); } glGenFramebuffersEXT(1, (GLuint *) &mFBO); if (mDepth) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); if (mStencil) { glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth); stop_glerror(); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth); stop_glerror(); } else { glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0); stop_glerror(); } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } stop_glerror(); } addColorAttachment(color_fmt); }
void LLRenderTarget::flush(BOOL fetch_depth) { gGL.flush(); if (!mFBO) { gGL.getTexUnit(0)->bind(this); glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, 0, 0, 0, 0, mResX, mResY); if (fetch_depth) { if (!mDepth) { allocateDepth(); } gGL.getTexUnit(0)->bind(this, true); glCopyTexImage2D(LLTexUnit::getInternalType(mUsage), 0, GL_DEPTH24_STENCIL8_EXT, 0, 0, mResX, mResY, 0); } } else { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } }
void LLRenderTarget::flush(bool fetch_depth) { gGL.flush(); if (!mFBO) { gGL.getTexUnit(0)->bind(this); glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, 0, 0, 0, 0, mResX, mResY); if (fetch_depth) { if (!mDepth) { allocateDepth(); } gGL.getTexUnit(0)->bind(this); glCopyTexImage2D(LLTexUnit::getInternalType(mUsage), 0, GL_DEPTH24_STENCIL8_EXT, 0, 0, mResX, mResY, 0); } gGL.getTexUnit(0)->disable(); } else { stop_glerror(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); stop_glerror(); if (mSampleBuffer) { LLGLEnable multisample(GL_MULTISAMPLE_ARB); stop_glerror(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); stop_glerror(); check_framebuffer_status(); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, mSampleBuffer->mFBO); check_framebuffer_status(); stop_glerror(); if(gGLManager.mIsATI) { glBlitFramebufferEXT(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); 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) { for (U32 i = 1; i < mTex.size(); ++i) { glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, LLTexUnit::getInternalType(mUsage), mTex[i], 0); stop_glerror(); glFramebufferRenderbufferEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, mSampleBuffer->mTex[i]); stop_glerror(); glBlitFramebufferEXT(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT, GL_NEAREST); stop_glerror(); } for (U32 i = 0; i < mTex.size(); ++i) { glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, LLTexUnit::getInternalType(mUsage), mTex[i], 0); stop_glerror(); glFramebufferRenderbufferEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, GL_RENDERBUFFER_EXT, mSampleBuffer->mTex[i]); stop_glerror(); } } } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } }
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(); if (!gGLManager.mHasFramebufferMultisample || !gGLManager.mHasFramebufferObject || !(sUseFBO || use_fbo)) return false; if(color_fmt != GL_RGBA) { llwarns << "Unsupported color format: " << color_fmt << llendl; return false; } //Restrict to valid sample count { mSamples = samples; //mSamples = llmin(mSamples, (U32)4); //Cap to prevent memory bloat. mSamples = llmin(mSamples, (U32) gGLManager.mMaxSamples); } if (mSamples <= 1) return false; mResX = resx; mResY = resy; mUsage = usage; mUseDepth = depth; mStencil = stencil; mColorFormat = color_fmt; { if (depth) { stop_glerror(); if(!allocateDepth()) { release(); return false; } stop_glerror(); } glGenFramebuffers(1, (GLuint *) &mFBO); glBindFramebuffer(GL_FRAMEBUFFER, mFBO); stop_glerror(); clear_glerror(); 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(); } return addColorAttachment(color_fmt); }
void LLRenderTarget::flush(bool fetch_depth) { gGL.flush(); if (!mFBO) { gGL.getTexUnit(0)->bind(this); glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, 0, 0, 0, 0, mResX, mResY); stop_glerror(); if (fetch_depth) { if (!mDepth) { allocateDepth(); } gGL.getTexUnit(0)->bind(this,true); glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, 0, 0, 0, 0, mResX, mResY); stop_glerror(); //glCopyTexImage2D(LLTexUnit::getInternalType(mUsage), 0, GL_DEPTH24_STENCIL8, 0, 0, mResX, mResY, 0); } gGL.getTexUnit(0)->disable(); } 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(); if(gGLManager.mIsATI) { glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_STENCIL_BUFFER_BIT, GL_NEAREST); } else { 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(); //Following case never currently evalutes true, but it's still good to have. if (mTex.size() > 1) { for (U32 i = 1; i < mTex.size(); ++i) { glDrawBuffer(GL_COLOR_ATTACHMENT0 + i); glReadBuffer(GL_COLOR_ATTACHMENT0 + i); stop_glerror(); glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT, GL_NEAREST); stop_glerror(); } /*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); } } }
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, LLTexUnit::eTextureType usage, BOOL use_fbo) { stop_glerror(); mResX = resx; mResY = resy; mUsage = usage; mUseDepth = depth; release(); glGenTextures(1, (GLuint *) &mTex); gGL.getTexUnit(0)->bindManual(mUsage, mTex); glTexImage2D(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, 0, color_fmt, GL_UNSIGNED_BYTE, NULL); glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (mUsage != LLTexUnit::TT_RECT_TEXTURE) { glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); } else { // ATI doesn't support mirrored repeat for rectangular textures. glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(LLTexUnit::getInternalType(mUsage), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } stop_glerror(); if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) { if (depth) { stop_glerror(); allocateDepth(); stop_glerror(); } glGenFramebuffersEXT(1, (GLuint *) &mFBO); stop_glerror(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); stop_glerror(); if (mDepth) { glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0); stop_glerror(); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0); stop_glerror(); } glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, LLTexUnit::getInternalType(mUsage), mTex, 0); stop_glerror(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); stop_glerror(); } }
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples) { stop_glerror(); release(); mResX = resx; mResY = resy; mStencil = stencil; mUsage = usage; mUseDepth = depth; mSamples = samples; mSamples = gGLManager.getNumFBOFSAASamples(mSamples); if (mSamples > 1 && gGLManager.mHasTextureMultisample) { mUsage = LLTexUnit::TT_MULTISAMPLE_TEXTURE; //no support for multisampled stencil targets yet mStencil = false; } else { mSamples = 0; } if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) { if (depth) { stop_glerror(); allocateDepth(); stop_glerror(); } glGenFramebuffers(1, (GLuint *) &mFBO); if (mDepth) { glBindFramebuffer(GL_FRAMEBUFFER, mFBO); if (mStencil) { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth); stop_glerror(); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth); stop_glerror(); } else { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0); stop_glerror(); } glBindFramebuffer(GL_FRAMEBUFFER, 0); } stop_glerror(); } addColorAttachment(color_fmt); }