Exemple #1
0
/*
============
R_InitFBOs
============
*/
void R_InitFBOs( void )
{
	int i;
	int width, height;

	ri.Printf( PRINT_DEVELOPER, "------- R_InitFBOs -------\n" );

	if ( !glConfig2.framebufferObjectAvailable )
	{
		return;
	}

	tr.numFBOs = 0;

#if !defined( USE_D3D10 )
	GL_CheckErrors();
#endif

	// make sure the render thread is stopped
	R_SyncRenderThread();

#if defined( USE_D3D10 )
	// TODO
#else

	if ( DS_STANDARD_ENABLED() )
	{
		// geometricRender FBO as G-Buffer for deferred shading
		ri.Printf( PRINT_ALL, "Deferred Shading enabled\n" );

		if ( glConfig2.textureNPOTAvailable )
		{
			width = glConfig.vidWidth;
			height = glConfig.vidHeight;
		}
		else
		{
			width = NearestPowerOfTwo( glConfig.vidWidth );
			height = NearestPowerOfTwo( glConfig.vidHeight );
		}

		tr.geometricRenderFBO = R_CreateFBO( "_geometricRender", width, height );
		R_BindFBO( tr.geometricRenderFBO );

#if 0

		if ( glConfig2.framebufferPackedDepthStencilAvailable )
		{
			R_AttachFBOTexturePackedDepthStencil( tr.depthRenderImage->texnum );
		}

		else if ( glConfig.hardwareType == GLHW_ATI || glConfig.hardwareType == GLHW_ATI_DX10 ) // || glConfig.hardwareType == GLHW_NV_DX10)
		{
			R_AttachFBOTextureDepth( tr.depthRenderImage->texnum );
		}
		else
#endif
		{
			R_AttachFBOTextureDepth( tr.depthRenderImage->texnum );
		}

		// enable all attachments as draw buffers
		//glDrawBuffers(4, geometricRenderTargets);

		R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.deferredRenderFBOImage->texnum, 0 );

		R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.deferredDiffuseFBOImage->texnum, 1 );

		R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.deferredNormalFBOImage->texnum, 2 );

		R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.deferredSpecularFBOImage->texnum, 3 );

		R_CheckFBO( tr.geometricRenderFBO );
	}
	else
	{
		// forward shading

		if ( glConfig2.textureNPOTAvailable )
		{
			width = glConfig.vidWidth;
			height = glConfig.vidHeight;
		}
		else
		{
			width = NearestPowerOfTwo( glConfig.vidWidth );
			height = NearestPowerOfTwo( glConfig.vidHeight );
		}

		// deferredRender FBO for the HDR or LDR context
		tr.deferredRenderFBO = R_CreateFBO( "_deferredRender", width, height );
		R_BindFBO( tr.deferredRenderFBO );

		R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.deferredRenderFBOImage->texnum, 0 );

#if 0

		if ( glConfig2.framebufferPackedDepthStencilAvailable )
		{
			R_AttachFBOTexturePackedDepthStencil( tr.depthRenderImage->texnum );
		}
		else if ( glConfig.hardwareType == GLHW_ATI || glConfig.hardwareType == GLHW_ATI_DX10 ) // || glConfig.hardwareType == GLHW_NV_DX10)
		{
			R_AttachFBOTextureDepth( tr.depthRenderImage->texnum );
		}
		else
#endif
		{
			R_AttachFBOTextureDepth( tr.depthRenderImage->texnum );
		}

		R_CheckFBO( tr.deferredRenderFBO );
	}

	if ( glConfig2.framebufferBlitAvailable )
	{
		if ( glConfig2.textureNPOTAvailable )
		{
			width = glConfig.vidWidth;
			height = glConfig.vidHeight;
		}
		else
		{
			width = NearestPowerOfTwo( glConfig.vidWidth );
			height = NearestPowerOfTwo( glConfig.vidHeight );
		}

		tr.occlusionRenderFBO = R_CreateFBO( "_occlusionRender", width, height );
		R_BindFBO( tr.occlusionRenderFBO );

		if ( glConfig.hardwareType == GLHW_ATI_DX10 )
		{
			//R_CreateFBOColorBuffer(tr.occlusionRenderFBO, GL_ALPHA16F, 0);
			R_CreateFBODepthBuffer( tr.occlusionRenderFBO, GL_DEPTH_COMPONENT16 );
		}
		else if ( glConfig.hardwareType == GLHW_NV_DX10 )
		{
			//R_CreateFBOColorBuffer(tr.occlusionRenderFBO, GL_ALPHA32F, 0);
			R_CreateFBODepthBuffer( tr.occlusionRenderFBO, GL_DEPTH_COMPONENT24 );
		}
		else if ( glConfig2.framebufferPackedDepthStencilAvailable )
		{
			//R_CreateFBOColorBuffer(tr.occlusionRenderFBO, GL_ALPHA32F, 0);
			R_CreateFBOPackedDepthStencilBuffer( tr.occlusionRenderFBO, GL_DEPTH24_STENCIL8_EXT );
		}
		else
		{
			//R_CreateFBOColorBuffer(tr.occlusionRenderFBO, GL_RGBA, 0);
			R_CreateFBODepthBuffer( tr.occlusionRenderFBO, GL_DEPTH_COMPONENT24 );
		}

		R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.occlusionRenderFBOImage->texnum, 0 );

		R_CheckFBO( tr.occlusionRenderFBO );
	}

	if ( r_shadows->integer >= SHADOWING_ESM16 && glConfig2.textureFloatAvailable )
	{
		// shadowMap FBOs for shadow mapping offscreen rendering
		for ( i = 0; i < MAX_SHADOWMAPS; i++ )
		{
			width = height = shadowMapResolutions[ i ];

			tr.shadowMapFBO[ i ] = R_CreateFBO( va( "_shadowMap%d", i ), width, height );
			R_BindFBO( tr.shadowMapFBO[ i ] );

			if ( ( glConfig.driverType == GLDRV_OPENGL3 ) || ( glConfig.hardwareType == GLHW_NV_DX10 || glConfig.hardwareType == GLHW_ATI_DX10 ) )
			{
				if ( r_shadows->integer == SHADOWING_ESM32 )
				{
					R_CreateFBOColorBuffer( tr.shadowMapFBO[ i ], GL_ALPHA32F_ARB, 0 );
				}
				else if ( r_shadows->integer == SHADOWING_VSM32 )
				{
					R_CreateFBOColorBuffer( tr.shadowMapFBO[ i ], GL_LUMINANCE_ALPHA32F_ARB, 0 );
				}
				else if ( r_shadows->integer == SHADOWING_EVSM32 )
				{
					if ( r_evsmPostProcess->integer )
					{
						R_CreateFBOColorBuffer( tr.shadowMapFBO[ i ], GL_ALPHA32F_ARB, 0 );
					}
					else
					{
						R_CreateFBOColorBuffer( tr.shadowMapFBO[ i ], GL_RGBA32F, 0 );
					}
				}
				else
				{
					R_CreateFBOColorBuffer( tr.shadowMapFBO[ i ], GL_RGBA16F, 0 );
				}
			}
			else
			{
				if ( r_shadows->integer == SHADOWING_ESM16 )
				{
					R_CreateFBOColorBuffer( tr.shadowMapFBO[ i ], GL_ALPHA16F_ARB, 0 );
				}
				else if ( r_shadows->integer == SHADOWING_VSM16 )
				{
					R_CreateFBOColorBuffer( tr.shadowMapFBO[ i ], GL_LUMINANCE_ALPHA16F_ARB, 0 );
				}
				else
				{
					R_CreateFBOColorBuffer( tr.shadowMapFBO[ i ], GL_RGBA16F, 0 );
				}
			}

			R_CreateFBODepthBuffer( tr.shadowMapFBO[ i ], GL_DEPTH_COMPONENT24 );

			R_CheckFBO( tr.shadowMapFBO[ i ] );
		}

		// sun requires different resolutions
		for ( i = 0; i < MAX_SHADOWMAPS; i++ )
		{
			width = height = sunShadowMapResolutions[ i ];

			tr.sunShadowMapFBO[ i ] = R_CreateFBO( va( "_sunShadowMap%d", i ), width, height );
			R_BindFBO( tr.sunShadowMapFBO[ i ] );

			if ( ( glConfig.driverType == GLDRV_OPENGL3 ) || ( glConfig.hardwareType == GLHW_NV_DX10 || glConfig.hardwareType == GLHW_ATI_DX10 ) )
			{
				if ( r_shadows->integer == SHADOWING_ESM32 )
				{
					R_CreateFBOColorBuffer( tr.sunShadowMapFBO[ i ], GL_ALPHA32F_ARB, 0 );
				}
				else if ( r_shadows->integer == SHADOWING_VSM32 )
				{
					R_CreateFBOColorBuffer( tr.sunShadowMapFBO[ i ], GL_LUMINANCE_ALPHA32F_ARB, 0 );
				}
				else if ( r_shadows->integer == SHADOWING_EVSM32 )
				{
					if ( !r_evsmPostProcess->integer )
					{
						R_CreateFBOColorBuffer( tr.sunShadowMapFBO[ i ], GL_RGBA32F, 0 );
					}
				}
				else
				{
					R_CreateFBOColorBuffer( tr.sunShadowMapFBO[ i ], GL_RGBA16F, 0 );
				}
			}
			else
			{
				if ( r_shadows->integer == SHADOWING_ESM16 )
				{
					R_CreateFBOColorBuffer( tr.sunShadowMapFBO[ i ], GL_ALPHA16F_ARB, 0 );
				}
				else if ( r_shadows->integer == SHADOWING_VSM16 )
				{
					R_CreateFBOColorBuffer( tr.sunShadowMapFBO[ i ], GL_LUMINANCE_ALPHA16F_ARB, 0 );
				}
				else
				{
					R_CreateFBOColorBuffer( tr.sunShadowMapFBO[ i ], GL_RGBA16F, 0 );
				}
			}

			R_CreateFBODepthBuffer( tr.sunShadowMapFBO[ i ], GL_DEPTH_COMPONENT24 );

			if ( r_shadows->integer == SHADOWING_EVSM32 && r_evsmPostProcess->integer )
			{
				R_AttachFBOTextureDepth( tr.sunShadowMapFBOImage[ i ]->texnum );

				/*
				Since we don't have a color attachment, the framebuffer will be considered incomplete.
				Consequently, we must inform the driver that we do not wish to render to the color buffer.
				We do this with a call to set the draw-buffer and read-buffer to GL_NONE:
				*/
				glDrawBuffer( GL_NONE );
				glReadBuffer( GL_NONE );
			}

			R_CheckFBO( tr.sunShadowMapFBO[ i ] );
		}
	}

	{
		if ( glConfig2.textureNPOTAvailable )
		{
			width = glConfig.vidWidth;
			height = glConfig.vidHeight;
		}
		else
		{
			width = NearestPowerOfTwo( glConfig.vidWidth );
			height = NearestPowerOfTwo( glConfig.vidHeight );
		}

		// portalRender FBO for portals, mirrors, water, cameras et cetera
		tr.portalRenderFBO = R_CreateFBO( "_portalRender", width, height );
		R_BindFBO( tr.portalRenderFBO );

		R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.portalRenderImage->texnum, 0 );

		R_CheckFBO( tr.portalRenderFBO );
	}

	{
		if ( glConfig2.textureNPOTAvailable )
		{
			width = glConfig.vidWidth * 0.25f;
			height = glConfig.vidHeight * 0.25f;
		}
		else
		{
			width = NearestPowerOfTwo( glConfig.vidWidth * 0.25f );
			height = NearestPowerOfTwo( glConfig.vidHeight * 0.25f );
		}

		tr.downScaleFBO_quarter = R_CreateFBO( "_downScale_quarter", width, height );
		R_BindFBO( tr.downScaleFBO_quarter );

		R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.downScaleFBOImage_quarter->texnum, 0 );
		R_CheckFBO( tr.downScaleFBO_quarter );

		tr.downScaleFBO_64x64 = R_CreateFBO( "_downScale_64x64", 64, 64 );
		R_BindFBO( tr.downScaleFBO_64x64 );

		R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.downScaleFBOImage_64x64->texnum, 0 );
		R_CheckFBO( tr.downScaleFBO_64x64 );

#if 0
		tr.downScaleFBO_16x16 = R_CreateFBO( "_downScale_16x16", 16, 16 );
		R_BindFBO( tr.downScaleFBO_16x16 );

		R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.downScaleFBOImage_16x16->texnum, 0 );
		R_CheckFBO( tr.downScaleFBO_16x16 );

		tr.downScaleFBO_4x4 = R_CreateFBO( "_downScale_4x4", 4, 4 );
		R_BindFBO( tr.downScaleFBO_4x4 );

		R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.downScaleFBOImage_4x4->texnum, 0 );
		R_CheckFBO( tr.downScaleFBO_4x4 );

		tr.downScaleFBO_1x1 = R_CreateFBO( "_downScale_1x1", 1, 1 );
		R_BindFBO( tr.downScaleFBO_1x1 );

		R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.downScaleFBOImage_1x1->texnum, 0 );
		R_CheckFBO( tr.downScaleFBO_1x1 );
#endif

		if ( glConfig2.textureNPOTAvailable )
		{
			width = glConfig.vidWidth * 0.25f;
			height = glConfig.vidHeight * 0.25f;
		}
		else
		{
			width = NearestPowerOfTwo( glConfig.vidWidth * 0.25f );
			height = NearestPowerOfTwo( glConfig.vidHeight * 0.25f );
		}

		tr.contrastRenderFBO = R_CreateFBO( "_contrastRender", width, height );
		R_BindFBO( tr.contrastRenderFBO );

		R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.contrastRenderFBOImage->texnum, 0 );

		R_CheckFBO( tr.contrastRenderFBO );

		for ( i = 0; i < 2; i++ )
		{
			tr.bloomRenderFBO[ i ] = R_CreateFBO( va( "_bloomRender%d", i ), width, height );
			R_BindFBO( tr.bloomRenderFBO[ i ] );

			R_AttachFBOTexture2D( GL_TEXTURE_2D, tr.bloomRenderFBOImage[ i ]->texnum, 0 );

			R_CheckFBO( tr.bloomRenderFBO[ i ] );
		}
	}

	GL_CheckErrors();
#endif // defined(USE_D3D10)

	R_BindNullFBO();
}
Exemple #2
0
/*
=====================
R_PerformanceCounters
=====================
*/
void R_PerformanceCounters(void)
{
	if (!r_speeds->integer)
	{
		// clear the counters even if we aren't printing
		Com_Memset(&tr.pc, 0, sizeof(tr.pc));
		Com_Memset(&backEnd.pc, 0, sizeof(backEnd.pc));
		return;
	}

	if (r_speeds->integer == RSPEEDS_GENERAL)
	{
		ri.Printf(PRINT_ALL, "%i views %i portals %i batches %i surfs %i leafs %i verts %i tris\n",
		          backEnd.pc.c_views, backEnd.pc.c_portals, backEnd.pc.c_batches, backEnd.pc.c_surfaces, tr.pc.c_leafs,
		          backEnd.pc.c_vertexes, backEnd.pc.c_indexes / 3);

		ri.Printf(PRINT_ALL, "%i lights %i bout %i pvsout %i queryout %i interactions\n",
		          tr.pc.c_dlights + tr.pc.c_slights - backEnd.pc.c_occlusionQueriesLightsCulled,
		          tr.pc.c_box_cull_light_out,
		          tr.pc.c_pvs_cull_light_out,
		          backEnd.pc.c_occlusionQueriesLightsCulled,
		          tr.pc.c_dlightInteractions + tr.pc.c_slightInteractions - backEnd.pc.c_occlusionQueriesInteractionsCulled);

		ri.Printf(PRINT_ALL, "%i draws %i queries %i CHC++ ms %i vbos %i ibos %i verts %i tris\n",
		          backEnd.pc.c_drawElements,
		          tr.pc.c_occlusionQueries,
		          tr.pc.c_CHCTime,
		          backEnd.pc.c_vboVertexBuffers, backEnd.pc.c_vboIndexBuffers,
		          backEnd.pc.c_vboVertexes, backEnd.pc.c_vboIndexes / 3);

		ri.Printf(PRINT_ALL, "%i multidraws %i primitives %i tris\n",
		          backEnd.pc.c_multiDrawElements,
		          backEnd.pc.c_multiDrawPrimitives,
		          backEnd.pc.c_multiVboIndexes / 3);
	}
	else if (r_speeds->integer == RSPEEDS_CULLING)
	{
		ri.Printf(PRINT_ALL, "(gen) %i sin %i sout %i pin %i pout\n",
		          tr.pc.c_sphere_cull_in, tr.pc.c_sphere_cull_out, tr.pc.c_plane_cull_in, tr.pc.c_plane_cull_out);

		ri.Printf(PRINT_ALL, "(patch) %i sin %i sclip %i sout %i bin %i bclip %i bout\n",
		          tr.pc.c_sphere_cull_patch_in, tr.pc.c_sphere_cull_patch_clip,
		          tr.pc.c_sphere_cull_patch_out, tr.pc.c_box_cull_patch_in,
		          tr.pc.c_box_cull_patch_clip, tr.pc.c_box_cull_patch_out);

		ri.Printf(PRINT_ALL, "(mdx) %i sin %i sclip %i sout %i bin %i bclip %i bout\n",
		          tr.pc.c_sphere_cull_mdx_in, tr.pc.c_sphere_cull_mdx_clip,
		          tr.pc.c_sphere_cull_mdx_out, tr.pc.c_box_cull_mdx_in, tr.pc.c_box_cull_mdx_clip, tr.pc.c_box_cull_mdx_out);

		ri.Printf(PRINT_ALL, "(md5) %i bin %i bclip %i bout\n",
		          tr.pc.c_box_cull_md5_in, tr.pc.c_box_cull_md5_clip, tr.pc.c_box_cull_md5_out);
	}
	else if (r_speeds->integer == RSPEEDS_VIEWCLUSTER)
	{
		ri.Printf(PRINT_ALL, "viewcluster: %i\n", tr.visClusters[tr.visIndex]);
	}
	else if (r_speeds->integer == RSPEEDS_LIGHTS)
	{
		ri.Printf(PRINT_ALL, "dlight srf:%i culled:%i\n", tr.pc.c_dlightSurfaces, tr.pc.c_dlightSurfacesCulled);

		ri.Printf(PRINT_ALL, "dlights:%i interactions:%i\n", tr.pc.c_dlights, tr.pc.c_dlightInteractions);

		ri.Printf(PRINT_ALL, "slights:%i interactions:%i\n", tr.pc.c_slights, tr.pc.c_slightInteractions);
	}
	else if (r_speeds->integer == RSPEEDS_SHADOWCUBE_CULLING)
	{
		ri.Printf(PRINT_ALL, "omni pyramid tests:%i bin:%i bclip:%i bout:%i\n",
		          tr.pc.c_pyramidTests, tr.pc.c_pyramid_cull_ent_in, tr.pc.c_pyramid_cull_ent_clip, tr.pc.c_pyramid_cull_ent_out);
	}
	else if (r_speeds->integer == RSPEEDS_FOG)
	{
		ri.Printf(PRINT_ALL, "fog srf:%i batches:%i\n", backEnd.pc.c_fogSurfaces, backEnd.pc.c_fogBatches);
	}
	else if (r_speeds->integer == RSPEEDS_FLARES)
	{
		ri.Printf(PRINT_ALL, "flare adds:%i tests:%i renders:%i\n",
		          backEnd.pc.c_flareAdds, backEnd.pc.c_flareTests, backEnd.pc.c_flareRenders);
	}
	else if (r_speeds->integer == RSPEEDS_OCCLUSION_QUERIES)
	{
		ri.Printf(PRINT_ALL, "occlusion queries:%i multi:%i saved:%i culled lights:%i culled entities:%i culled leafs:%i response time:%i fetch time:%i\n",
		          backEnd.pc.c_occlusionQueries,
		          backEnd.pc.c_occlusionQueriesMulti,
		          backEnd.pc.c_occlusionQueriesSaved,
		          backEnd.pc.c_occlusionQueriesLightsCulled,
		          backEnd.pc.c_occlusionQueriesEntitiesCulled,
		          backEnd.pc.c_occlusionQueriesLeafsCulled,
		          backEnd.pc.c_occlusionQueriesResponseTime,
		          backEnd.pc.c_occlusionQueriesFetchTime);
	}
#if 0
	else if (r_speeds->integer == RSPEEDS_DEPTH_BOUNDS_TESTS)
	{
		ri.Printf(PRINT_ALL, "depth bounds tests:%i rejected:%i\n", tr.pc.c_depthBoundsTests, tr.pc.c_depthBoundsTestsRejected);
	}
#endif
	else if (r_speeds->integer == RSPEEDS_SHADING_TIMES)
	{
		if (DS_STANDARD_ENABLED())
		{
			ri.Printf(PRINT_ALL, "deferred shading times: g-buffer:%i lighting:%i translucent:%i\n", backEnd.pc.c_deferredGBufferTime,
			          backEnd.pc.c_deferredLightingTime, backEnd.pc.c_forwardTranslucentTime);
		}
		else
		{
			ri.Printf(PRINT_ALL, "forward shading times: ambient:%i lighting:%i\n", backEnd.pc.c_forwardAmbientTime,
			          backEnd.pc.c_forwardLightingTime);
		}
	}
	else if (r_speeds->integer == RSPEEDS_CHC)
	{
		ri.Printf(PRINT_ALL, "%i CHC++ ms %i queries %i multi queries %i saved\n",
		          tr.pc.c_CHCTime,
		          tr.pc.c_occlusionQueries,
		          tr.pc.c_occlusionQueriesMulti,
		          tr.pc.c_occlusionQueriesSaved);
	}
	else if (r_speeds->integer == RSPEEDS_NEAR_FAR)
	{
		ri.Printf(PRINT_ALL, "zNear: %.0f zFar: %.0f\n", tr.viewParms.zNear, tr.viewParms.zFar);
	}
	else if (r_speeds->integer == RSPEEDS_DECALS)
	{
		ri.Printf(PRINT_ALL, "decal projectors: %d test surfs: %d clip surfs: %d decal surfs: %d created: %d\n",
		          tr.pc.c_decalProjectors, tr.pc.c_decalTestSurfaces, tr.pc.c_decalClipSurfaces, tr.pc.c_decalSurfaces,
		          tr.pc.c_decalSurfacesCreated);
	}

	Com_Memset(&tr.pc, 0, sizeof(tr.pc));
	Com_Memset(&backEnd.pc, 0, sizeof(backEnd.pc));
}