Wedged high-res non-tiled deferred snapshot logic into LLViewerWindow::rawRawSnapshot

This commit is contained in:
Shyotl
2013-02-25 12:59:17 -06:00
parent 34cf0329ab
commit fd21197d2a
4 changed files with 85 additions and 38 deletions

View File

@@ -51,11 +51,13 @@ void check_framebuffer_status()
}
bool LLRenderTarget::sUseFBO = false;
U32 LLRenderTarget::sCurFBO = 0;
LLRenderTarget::LLRenderTarget() :
mResX(0),
mResY(0),
mFBO(0),
mPreviousFBO(0),
mDepth(0),
mStencil(0),
mUseDepth(false),
@@ -117,6 +119,9 @@ void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer)
bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo)
{
resx = llmin(resx, (U32) 4096);
resy = llmin(resy, (U32) 4096);
stop_glerror();
release();
stop_glerror();
@@ -156,7 +161,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
stop_glerror();
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
}
stop_glerror();
@@ -173,10 +178,19 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
}
U32 offset = mTex.size();
if (offset >= 4 ||
(offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers)))
if( offset >= 4 )
{
llerrs << "Too many color attachments!" << llendl;
llwarns << "Too many color attachments" << llendl;
llassert( offset < 4 );
return false;
}
if( offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers) )
{
llwarns << "FBO not used or no drawbuffers available; mFBO=" << (U32)mFBO << " gGLManager.mHasDrawBuffers=" << (U32)gGLManager.mHasDrawBuffers << llendl;
llassert( mFBO != 0 );
llassert( gGLManager.mHasDrawBuffers );
return false;
}
U32 tex;
@@ -234,7 +248,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
check_framebuffer_status();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
}
mTex.push_back(tex);
@@ -329,7 +343,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
check_framebuffer_status();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
target.mUseDepth = true;
}
@@ -400,14 +414,18 @@ void LLRenderTarget::bindTarget()
if (mFBO)
{
stop_glerror();
mPreviousFBO = sCurFBO;
if (mSampleBuffer)
{
mSampleBuffer->bindTarget(this);
sCurFBO = mSampleBuffer->mFBO;
stop_glerror();
}
else
{
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
sCurFBO = mFBO;
stop_glerror();
if (gGLManager.mHasDrawBuffers)
{ //setup multiple render targets
@@ -434,16 +452,6 @@ void LLRenderTarget::bindTarget()
sBoundTarget = this;
}
// static
void LLRenderTarget::unbindTarget()
{
if (gGLManager.mHasFramebufferObject)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
sBoundTarget = NULL;
}
void LLRenderTarget::clear(U32 mask_in)
{
U32 mask = GL_COLOR_BUFFER_BIT;
@@ -512,10 +520,7 @@ void LLRenderTarget::flush(bool fetch_depth)
else
{
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
stop_glerror();
if (mSampleBuffer)
if(mSampleBuffer)
{
LLGLEnable multisample(GL_MULTISAMPLE);
stop_glerror();
@@ -570,10 +575,14 @@ void LLRenderTarget::flush(bool fetch_depth)
stop_glerror();
}*/
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFBO);
sCurFBO = mPreviousFBO;
stop_glerror();
}
}
void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter)
{
@@ -604,7 +613,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
stop_glerror();
glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
stop_glerror();
}
else
@@ -627,7 +636,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
stop_glerror();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
stop_glerror();
}
}
@@ -661,7 +670,7 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0
if(mask)
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
stop_glerror();
}
}
@@ -810,7 +819,7 @@ bool LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth
}
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
stop_glerror();
@@ -889,7 +898,7 @@ bool LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset, GL_RENDERBUFFER, tex);
check_framebuffer_status();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
}
mTex.push_back(tex);

View File

@@ -65,6 +65,7 @@ public:
//whether or not to use FBO implementation
static bool sUseFBO;
static U32 sBytesAllocated;
static U32 sCurFBO;
LLRenderTarget();
virtual ~LLRenderTarget();
@@ -101,9 +102,6 @@ public:
//applies appropriate viewport
virtual void bindTarget();
//unbind target for rendering
static void unbindTarget();
//clear render targer, clears depth buffer if present,
//uses scissor rect if in copy-to-texture mode
void clear(U32 mask = 0xFFFFFFFF);
@@ -156,6 +154,7 @@ protected:
std::vector<U32> mTex;
std::vector<U32> mInternalFormat;
U32 mFBO;
U32 mPreviousFBO;
U32 mDepth;
bool mStencil;
bool mUseDepth;

View File

@@ -4349,8 +4349,8 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw,
// Copy screen to a buffer
LLRect const window_rect = show_ui ? getWindowRectRaw() : getWorldViewRectRaw();
S32 const window_width = window_rect.getWidth();
S32 const window_height = window_rect.getHeight();
S32 window_width = window_rect.getWidth();
S32 window_height = window_rect.getHeight();
// SNAPSHOT
@@ -4378,7 +4378,7 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw,
S32 buffer_x_offset = 0;
S32 buffer_y_offset = 0;
F32 scale_factor;
F32 scale_factor = 1.0f;
S32 image_buffer_x;
S32 image_buffer_y;
@@ -4386,6 +4386,36 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw,
// snapshot fits precisely inside window, it is the portion of the window with the correct aspect.
F32 snapshot_width = (snapshot_aspect > window_aspect) ? (F32)window_width : window_height * snapshot_aspect;
F32 snapshot_height = (snapshot_aspect < window_aspect) ? (F32)window_height : window_width / snapshot_aspect;
//This is what I would classify as a hack. If in deferred then do not tile (window_*=snapshot_*=image_*, ratio=scale_factor=1.f)
S32 original_width = 0;
S32 original_height = 0;
bool reset_deferred = false;
LLRenderTarget scratch_space;
if ((image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui)
{
if (scratch_space.allocate(image_width, image_height, GL_RGBA, true, true))
{
original_width = gPipeline.mDeferredScreen.getWidth();
original_height = gPipeline.mDeferredScreen.getHeight();
if (gPipeline.allocateScreenBuffer(image_width, image_height))
{
image_width = snapshot_width = window_width = scratch_space.getWidth();
image_height = snapshot_height = window_height = scratch_space.getHeight();
reset_deferred = true;
mWindowRectRaw.set(0, image_height, image_width, 0);
scratch_space.bindTarget();
}
else
{
scratch_space.release();
gPipeline.allocateScreenBuffer(original_width, original_height);
}
}
}
// ratio is the ratio snapshot/image', where image' is a rectangle with aspect snapshot_aspect that precisely contains image.
// Thus image_width' / image_height' == aspect ==> snapshot_width / image_width' == snapshot_height / image_height'.
// Since image' precisely contains image, one of them is equal (ie, image_height' = image_height) and the other is larger
@@ -4406,7 +4436,7 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw,
image_buffer_x = llround(snapshot_width * scale_factor);
image_buffer_y = llround(snapshot_height * scale_factor);
if (llmax(image_buffer_x, image_buffer_y) > max_size && // Boundary check to avoid memory overflow.
internal_scale <= 1.f) // SHY_MOD: If supersampling... Don't care about max_size.
internal_scale <= 1.f && !reset_deferred) // SHY_MOD: If supersampling... Don't care about max_size.
{
// Too big, clamp.
continue;
@@ -4414,6 +4444,8 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw,
// Done.
break;
}
// Center the buffer.
buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f);
buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f);
@@ -4577,6 +4609,15 @@ bool LLViewerWindow::rawRawSnapshot(LLImageRaw *raw,
// objects on them.
gPipeline.resetDrawOrders();
}
if (reset_deferred)
{
mWindowRectRaw = window_rect;
scratch_space.flush();
scratch_space.release();
gPipeline.allocateScreenBuffer(original_width, original_height);
}
if (is_tiling)
{

View File

@@ -1020,7 +1020,7 @@ void LLPipeline::createGLBuffers()
{
mGlow[i].bindTarget();
mGlow[i].clear();
mGlow[i].unbindTarget();
mGlow[i].flush();
}
}
@@ -6728,11 +6728,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b
gGlowProgram.unbind();
if (LLRenderTarget::sUseFBO)
/*if (LLRenderTarget::sUseFBO)
{
LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}*/
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
@@ -8414,8 +8414,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
}
last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
LLRenderTarget::unbindTarget();
LLPipeline::sReflectionRender = FALSE;
if (!LLRenderTarget::sUseFBO)