diff options
Diffstat (limited to 'indra/newview')
| -rwxr-xr-x | indra/newview/app_settings/settings.xml | 12 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl | 1 | ||||
| -rwxr-xr-x | indra/newview/llfloaterpreference.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/lltexturecache.cpp | 15 | ||||
| -rwxr-xr-x | indra/newview/llviewerwindow.cpp | 55 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 80 | ||||
| -rw-r--r-- | indra/newview/pipeline.h | 19 | 
7 files changed, 152 insertions, 35 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 199e4f459d..7deb1284b9 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -14070,5 +14070,17 @@          <real>1.0</real>        </array>      </map> + +  <key>SimulateFBOFailure</key> +  <map> +    <key>Comment</key> +    <string>[DEBUG] Make allocateScreenBuffer return false.  Used to test error handling.</string> +    <key>Persist</key> +    <integer>0</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map>  </map>  </llsd> diff --git a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl index e02a7b405b..2cef8f2a5d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl @@ -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; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 5752f839ce..542e96cf16 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -750,7 +750,10 @@ void LLFloaterPreference::onClose(bool app_quitting)  {  	gSavedSettings.setS32("LastPrefTab", getChild<LLTabContainer>("pref core")->getCurrentPanelIndex());  	LLPanelLogin::setAlwaysRefresh(false); -	cancel(); +	if (!app_quitting) +	{ +		cancel(); +	}  }  void LLFloaterPreference::onOpenHardwareSettings() diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index a61e2d5c86..2d463f0afa 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1861,7 +1861,12 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d  		mFastCachep->seek(APR_SET, offset);		 -		llassert_always(mFastCachep->read(head, TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) == TEXTURE_FAST_CACHE_ENTRY_OVERHEAD); +		if(mFastCachep->read(head, TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) != TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) +		{ +			//cache corrupted or under thread race condition +			closeFastCache();  +			return NULL; +		}  		S32 image_size = head[0] * head[1] * head[2];  		if(!image_size) //invalid @@ -1872,7 +1877,13 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d  		discardlevel = head[3];  		data =  (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), image_size); -		llassert_always(mFastCachep->read(data, image_size) == image_size); +		if(mFastCachep->read(data, image_size) != image_size) +		{ +			FREE_MEM(LLImageBase::getPrivatePool(), data); +			closeFastCache(); +			return NULL; +		} +  		closeFastCache();  	}  	LLPointer<LLImageRaw> raw = new LLImageRaw(data, head[0], head[1], head[2], true); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 29ca7dac27..1def2db829 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4237,14 +4237,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) @@ -4433,11 +4467,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;  } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index ea2dc60b07..ab45bd3d3b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -779,18 +779,57 @@ void LLPipeline::allocatePhysicsBuffer()  	}  } -void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) +bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  {  	refreshCachedSettings(); -	U32 samples = RenderFSAASamples; +	 +	bool save_settings = sRenderDeferred; +	if (save_settings) +	{ +		// Set this flag in case we crash while resizing window or allocating space for deferred rendering targets +		gSavedSettings.setBOOL("RenderInitError", TRUE); +		gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); +	} + +	eFBOStatus ret = doAllocateScreenBuffer(resX, resY); + +	if (save_settings) +	{ +		// don't disable shaders on next session +		gSavedSettings.setBOOL("RenderInitError", FALSE); +		gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); +	} +	 +	if (ret == FBO_FAILURE) +	{ //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled +		//NOTE: if the session closes successfully after this call, deferred rendering will be  +		// disabled on future sessions +		if (LLPipeline::sRenderDeferred) +		{ +			gSavedSettings.setBOOL("RenderDeferred", FALSE); +			LLPipeline::refreshCachedSettings(); +		} +	} + +	return ret == FBO_SUCCESS_FULLRES; +} -	//try to allocate screen buffers at requested resolution and samples + +LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY) +{ +	// try to allocate screen buffers at requested resolution and samples  	// - on failure, shrink number of samples and try again  	// - 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 +	U32 samples = RenderFSAASamples; + +	eFBOStatus ret = FBO_SUCCESS_FULLRES;  	if (!allocateScreenBuffer(resX, resY, samples))  	{ +		//failed to allocate at requested specification, return false +		ret = FBO_FAILURE; +  		releaseScreenBuffers();  		//reduce number of samples   		while (samples > 0) @@ -798,7 +837,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  			samples /= 2;  			if (allocateScreenBuffer(resX, resY, samples))  			{ //success -				return; +				return FBO_SUCCESS_LOWRES;  			}  			releaseScreenBuffers();  		} @@ -811,22 +850,23 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  			resY /= 2;  			if (allocateScreenBuffer(resX, resY, samples))  			{ -				return; +				return FBO_SUCCESS_LOWRES;  			}  			releaseScreenBuffers();  			resX /= 2;  			if (allocateScreenBuffer(resX, resY, samples))  			{ -				return; +				return FBO_SUCCESS_LOWRES;  			}  			releaseScreenBuffers();  		}  		llwarns << "Unable to allocate screen buffer at any resolution!" << llendl;  	} -} +	return ret; +}  bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  { @@ -854,10 +894,6 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  	if (LLPipeline::sRenderDeferred)  	{ -		// Set this flag in case we crash while resizing window or allocating space for deferred rendering targets -		gSavedSettings.setBOOL("RenderInitError", TRUE); -		gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); -  		S32 shadow_detail = RenderShadowDetail;  		BOOL ssao = RenderDeferredSSAO; @@ -869,7 +905,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  		{ @@ -903,7 +939,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  			}  		} -		U32 width = nhpo2(U32(resX*scale))/2; +		U32 width = (U32) (resX*scale);  		U32 height = width;  		if (shadow_detail > 1) @@ -922,9 +958,11 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  			}  		} -		// don't disable shaders on next session -		gSavedSettings.setBOOL("RenderInitError", FALSE); -		gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); +		//HACK make screenbuffer allocations start failing after 30 seconds +		if (gSavedSettings.getBOOL("SimulateFBOFailure")) +		{ +			return false; +		}  	}  	else  	{ @@ -7117,11 +7155,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; @@ -7997,10 +8035,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); @@ -8772,8 +8806,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  		}  		last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate; -		LLRenderTarget::unbindTarget(); -  		LLPipeline::sReflectionRender = FALSE;  		if (!LLRenderTarget::sUseFBO) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 7a0ca86231..36abeca295 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -119,8 +119,25 @@ 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); + +	typedef enum { +		FBO_SUCCESS_FULLRES = 0, +		FBO_SUCCESS_LOWRES, +		FBO_FAILURE +	} eFBOStatus; + +private: +	//implementation of above, wrapped for easy error handling +	eFBOStatus doAllocateScreenBuffer(U32 resX, U32 resY); +public: + +	//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);  | 
