master
Dave Parks 2012-07-18 15:50:45 -05:00
commit 725cf540a5
6 changed files with 90 additions and 42 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),
@ -107,6 +109,9 @@ void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
{
resx = llmin(resx, (U32) 4096);
resy = llmin(resy, (U32) 4096);
stop_glerror();
release();
stop_glerror();
@ -146,7 +151,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();
@ -224,7 +229,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
check_framebuffer_status();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
}
mTex.push_back(tex);
@ -313,7 +318,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
check_framebuffer_status();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
target.mUseDepth = true;
}
@ -376,9 +381,13 @@ void LLRenderTarget::bindTarget()
{
if (mFBO)
{
mPreviousFBO = sCurFBO;
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
sCurFBO = mFBO;
stop_glerror();
if (gGLManager.mHasDrawBuffers)
{ //setup multiple render targets
@ -404,16 +413,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;
@ -479,7 +478,8 @@ void LLRenderTarget::flush(bool fetch_depth)
else
{
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFBO);
sCurFBO = mPreviousFBO;
stop_glerror();
}
}
@ -509,7 +509,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
@ -526,7 +526,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();
}
}
@ -552,7 +552,7 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0
stop_glerror();
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
stop_glerror();
}
}

View File

@ -63,6 +63,7 @@ public:
//whether or not to use FBO implementation
static bool sUseFBO;
static U32 sBytesAllocated;
static U32 sCurFBO;
LLRenderTarget();
~LLRenderTarget();
@ -96,9 +97,6 @@ public:
//applies appropriate viewport
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);
@ -148,6 +146,7 @@ protected:
std::vector<U32> mTex;
std::vector<U32> mInternalFormat;
U32 mFBO;
U32 mPreviousFBO;
U32 mDepth;
bool mStencil;
bool mUseDepth;

View File

@ -2093,7 +2093,6 @@ uniform sampler2D diffuseMap;
uniform vec2 rcp_screen_res;
uniform vec4 rcp_frame_opt;
uniform vec4 rcp_frame_opt2;
uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
VARYING vec2 vary_tc;

View File

@ -4225,14 +4225,48 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
image_height = llmin(image_height, window_height);
}
S32 original_width = 0;
S32 original_height = 0;
bool reset_deferred = false;
LLRenderTarget scratch_space;
F32 scale_factor = 1.0f ;
if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height))
{
// if image cropping or need to enlarge the scene, compute a scale_factor
F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
snapshot_width = (S32)(ratio * image_width) ;
snapshot_height = (S32)(ratio * image_height) ;
scale_factor = llmax(1.0f, 1.0f / ratio) ;
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))
{
window_width = image_width;
window_height = image_height;
snapshot_width = image_width;
snapshot_height = image_height;
reset_deferred = true;
mWorldViewRectRaw.set(0, image_height, image_width, 0);
scratch_space.bindTarget();
}
else
{
scratch_space.release();
gPipeline.allocateScreenBuffer(original_width, original_height);
}
}
}
if (!reset_deferred)
{
// if image cropping or need to enlarge the scene, compute a scale_factor
F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
snapshot_width = (S32)(ratio * image_width) ;
snapshot_height = (S32)(ratio * image_height) ;
scale_factor = llmax(1.0f, 1.0f / ratio) ;
}
}
if (show_ui && scale_factor > 1.f)
@ -4421,11 +4455,20 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
gPipeline.resetDrawOrders();
}
if (reset_deferred)
{
mWorldViewRectRaw = window_rect;
scratch_space.flush();
scratch_space.release();
gPipeline.allocateScreenBuffer(original_width, original_height);
}
if (high_res)
{
send_agent_resume();
}
return ret;
}

View File

@ -774,7 +774,7 @@ void LLPipeline::allocatePhysicsBuffer()
}
}
void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
{
refreshCachedSettings();
U32 samples = RenderFSAASamples;
@ -784,8 +784,13 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
// - if not multisampled, shrink resolution and try again (favor X resolution over Y)
// Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state
bool ret = true;
if (!allocateScreenBuffer(resX, resY, samples))
{
//failed to allocate at requested specification, return false
ret = false;
releaseScreenBuffers();
//reduce number of samples
while (samples > 0)
@ -793,7 +798,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
samples /= 2;
if (allocateScreenBuffer(resX, resY, samples))
{ //success
return;
return ret;
}
releaseScreenBuffers();
}
@ -806,20 +811,22 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
resY /= 2;
if (allocateScreenBuffer(resX, resY, samples))
{
return;
return ret;
}
releaseScreenBuffers();
resX /= 2;
if (allocateScreenBuffer(resX, resY, samples))
{
return;
return ret;
}
releaseScreenBuffers();
}
llwarns << "Unable to allocate screen buffer at any resolution!" << llendl;
}
return ret;
}
@ -864,7 +871,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (samples > 0)
{
if (!mFXAABuffer.allocate(nhpo2(resX), nhpo2(resY), GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
}
else
{
@ -898,7 +905,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
}
U32 width = nhpo2(U32(resX*scale))/2;
U32 width = resX*scale;
U32 height = width;
if (shadow_detail > 1)
@ -6701,11 +6708,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
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;
@ -7581,10 +7588,6 @@ void LLPipeline::renderDeferredLighting()
gGL.popMatrix();
stop_glerror();
//copy depth and stencil from deferred screen
//mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
// 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
mScreen.bindTarget();
// clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
glClearColor(0,0,0,0);
@ -8355,8 +8358,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
}
last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
LLRenderTarget::unbindTarget();
LLPipeline::sReflectionRender = FALSE;
if (!LLRenderTarget::sUseFBO)

View File

@ -119,8 +119,14 @@ public:
void createGLBuffers();
void createLUTBuffers();
void allocateScreenBuffer(U32 resX, U32 resY);
//allocate the largest screen buffer possible up to resX, resY
//returns true if full size buffer allocated, false if some other size is allocated
bool allocateScreenBuffer(U32 resX, U32 resY);
//attempt to allocate screen buffers at resX, resY
//returns true if allocation successful, false otherwise
bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples);
void allocatePhysicsBuffer();
void resetVertexBuffers(LLDrawable* drawable);