Wedged high-res non-tiled deferred snapshot logic into LLViewerWindow::rawRawSnapshot
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user