Started to refactor RB_ functions into idRenderBackend. DOES NOT COMPILE

This commit is contained in:
Robert Beckebans 2017-09-03 23:17:44 +02:00
parent 530b382929
commit a5b5840ca7
11 changed files with 1854 additions and 1161 deletions

View file

@ -79,7 +79,7 @@ void Framebuffer::Init()
{
cmdSystem->AddCommand( "listFramebuffers", R_ListFramebuffers_f, CMD_FL_RENDERER, "lists framebuffers" );
backEnd.glState.currentFramebuffer = NULL;
tr.backend.currentFramebuffer = NULL;
// SHADOWMAPS
@ -340,33 +340,33 @@ void Framebuffer::Bind()
{
RENDERLOG_PRINTF( "Framebuffer::Bind( %s )\n", fboName.c_str() );
if( backEnd.glState.currentFramebuffer != this )
if( tr.backend.currentFramebuffer != this )
{
glBindFramebuffer( GL_FRAMEBUFFER, frameBuffer );
backEnd.glState.currentFramebuffer = this;
tr.backend.currentFramebuffer = this;
}
}
bool Framebuffer::IsBound()
{
return ( backEnd.glState.currentFramebuffer == this );
return ( tr.backend.currentFramebuffer == this );
}
void Framebuffer::Unbind()
{
RENDERLOG_PRINTF( "Framebuffer::Unbind()\n" );
//if(backEnd.glState.framebuffer != NULL)
//if(tr.backend.framebuffer != NULL)
{
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glBindRenderbuffer( GL_RENDERBUFFER, 0 );
backEnd.glState.currentFramebuffer = NULL;
tr.backend.currentFramebuffer = NULL;
}
}
bool Framebuffer::IsDefaultFramebufferActive()
{
return ( backEnd.glState.currentFramebuffer == NULL );
return ( tr.backend.currentFramebuffer == NULL );
}
void Framebuffer::AddColorBuffer( int format, int index, int multiSamples )

View file

@ -71,76 +71,15 @@ static const int OCCLUSION_QUERY_TOO_OLD = -1;
#define USE_CORE_PROFILE
struct wrapperContext_t
{
};
/*
================================================
wrapperConfig_t
================================================
*/
struct wrapperConfig_t
{
// rendering options and settings
bool disableStateCaching;
bool lazyBindPrograms;
bool lazyBindParms;
bool lazyBindTextures;
bool stripFragmentBranches;
bool skipDetailTris;
bool singleTriangle;
// values for polygon offset
float polyOfsFactor;
float polyOfsUnits;
// global texture filter settings
int textureMinFilter;
int textureMaxFilter;
int textureMipFilter;
float textureAnisotropy;
float textureLODBias;
};
/*
================================================
wrapperStats_t
================================================
*/
struct wrapperStats_t
{
int c_queriesIssued;
int c_queriesPassed;
int c_queriesWaitTime;
int c_queriesTooOld;
int c_programsBound;
int c_drawElements;
int c_drawIndices;
int c_drawVertices;
};
/*
================================================================================================
API
================================================================================================
*/
void GL_SetWrapperContext( const wrapperContext_t& context );
void GL_SetWrapperConfig( const wrapperConfig_t& config );
void GL_SetTimeDelta( uint64 delta ); // delta from GPU to CPU microseconds
void GL_StartFrame( int frame ); // inserts a timing mark for the start of the GPU frame
void GL_EndFrame(); // inserts a timing mark for the end of the GPU frame
void GL_WaitForEndFrame(); // wait for the GPU to reach the last end frame marker
void GL_GetLastFrameTime( uint64& startGPUTimeMicroSec, uint64& endGPUTimeMicroSec ); // GPU time between GL_StartFrame() and GL_EndFrame()
// GPU time between GL_StartFrame() and GL_EndFrame()
void GL_StartDepthPass( const idScreenRect& rect );
void GL_FinishDepthPass();
void GL_GetDepthPassRect( idScreenRect& rect );
void GL_SetDefaultState();
void GL_State( uint64 stateVector, bool forceGlState = false );
uint64 GL_GetCurrentState();
uint64 GL_GetCurrentStateMinusStencil();
void GL_Cull( int cullType );
@ -165,22 +104,14 @@ ID_INLINE void GL_ViewportAndScissor( const idScreenRect& rect )
GL_Scissor( rect );
}
// RB: HDR parm
void GL_Clear( bool color, bool depth, bool stencil, byte stencilValue, float r, float g, float b, float a, bool clearHDR = true );
// RB end
void GL_PolygonOffset( float scale, float bias );
void GL_DepthBoundsTest( const float zmin, const float zmax );
//void GL_Color( float* color );
// RB begin
void GL_Color( const idVec3& color );
void GL_Color( const idVec4& color );
// RB end
void GL_Color( float r, float g, float b );
void GL_Color( float r, float g, float b, float a );
void GL_SelectTexture( int unit );
void GL_Flush(); // flush the GPU command buffer
void GL_Finish(); // wait for the GPU to have executed all commands
// RB begin
@ -192,8 +123,7 @@ bool GL_CheckErrors_( const char* filename, int line );
#endif
// RB end
wrapperStats_t GL_GetCurrentStats();
void GL_ClearStats();
#endif // !__GRAPHICSAPIWRAPPER_H__

View file

@ -447,7 +447,6 @@ private:
#endif
};
// data is RGBA
void R_WriteTGA( const char* filename, const byte* data, int width, int height, bool flipVertical = false, const char* basePath = "fs_savepath" );
// data is in top-to-bottom raster order unless flipVertical is set
@ -498,9 +497,6 @@ public:
// reloads all apropriate images after a vid_restart
void ReloadImages( bool all );
// unbind all textures from all texture units
void UnbindAll();
// disable the active texture unit
void BindNull();

View file

@ -742,21 +742,7 @@ void R_CombineCubeImages_f( const idCmdArgs& args )
common->SetRefreshOnPrint( false );
}
/*
===============
UnbindAll
===============
*/
void idImageManager::UnbindAll()
{
int oldTMU = backEnd.glState.currenttmu;
for( int i = 0; i < MAX_PROG_TEXTURE_PARMS; ++i )
{
backEnd.glState.currenttmu = i;
BindNull();
}
backEnd.glState.currenttmu = oldTMU;
}
/*
===============

View file

@ -667,7 +667,6 @@ Automatically enables 2D mapping or cube mapping if needed
*/
void idImage::Bind()
{
RENDERLOG_PRINTF( "idImage::Bind( %s )\n", GetName() );
// load the image if necessary (FIXME: not SMP safe!)
@ -677,7 +676,7 @@ void idImage::Bind()
ActuallyLoadImage( true );
}
const int texUnit = backEnd.glState.currenttmu;
const int texUnit = tr.backend.currenttmu;
// RB: added support for more types
tmu_t* tmu = &backEnd.glState.tmu[texUnit];

View file

@ -31,6 +31,7 @@ If you have questions concerning this license or the applicable additional terms
#include "precompiled.h"
#include "../RenderCommon.h"
#include "../RenderBackend.h"
#include "../../framework/Common_local.h"
idCVar r_drawFlickerBox( "r_drawFlickerBox", "0", CVAR_RENDERER | CVAR_BOOL, "visual test for dropping frames" );
@ -52,6 +53,652 @@ static GLsync renderSync[2];
void GLimp_SwapBuffers();
void RB_SetMVP( const idRenderMatrix& mvp );
/*
=============
idRenderBackend::DrawElementsWithCounters
=============
*/
void idRenderBackend::DrawElementsWithCounters( const drawSurf_t* surf )
{
// get vertex buffer
const vertCacheHandle_t vbHandle = surf->ambientCache;
idVertexBuffer* vertexBuffer;
if( vertexCache.CacheIsStatic( vbHandle ) )
{
vertexBuffer = &vertexCache.staticData.vertexBuffer;
}
else
{
const uint64 frameNum = ( int )( vbHandle >> VERTCACHE_FRAME_SHIFT ) & VERTCACHE_FRAME_MASK;
if( frameNum != ( ( vertexCache.currentFrame - 1 ) & VERTCACHE_FRAME_MASK ) )
{
idLib::Warning( "RB_DrawElementsWithCounters, vertexBuffer == NULL" );
return;
}
vertexBuffer = &vertexCache.frameData[vertexCache.drawListNum].vertexBuffer;
}
const int vertOffset = ( int )( vbHandle >> VERTCACHE_OFFSET_SHIFT ) & VERTCACHE_OFFSET_MASK;
// get index buffer
const vertCacheHandle_t ibHandle = surf->indexCache;
idIndexBuffer* indexBuffer;
if( vertexCache.CacheIsStatic( ibHandle ) )
{
indexBuffer = &vertexCache.staticData.indexBuffer;
}
else
{
const uint64 frameNum = ( int )( ibHandle >> VERTCACHE_FRAME_SHIFT ) & VERTCACHE_FRAME_MASK;
if( frameNum != ( ( vertexCache.currentFrame - 1 ) & VERTCACHE_FRAME_MASK ) )
{
idLib::Warning( "RB_DrawElementsWithCounters, indexBuffer == NULL" );
return;
}
indexBuffer = &vertexCache.frameData[vertexCache.drawListNum].indexBuffer;
}
// RB: 64 bit fixes, changed int to GLintptr
const GLintptr indexOffset = ( GLintptr )( ibHandle >> VERTCACHE_OFFSET_SHIFT ) & VERTCACHE_OFFSET_MASK;
// RB end
RENDERLOG_PRINTF( "Binding Buffers: %p:%i %p:%i\n", vertexBuffer, vertOffset, indexBuffer, indexOffset );
if( surf->jointCache )
{
// DG: this happens all the time in the erebus1 map with blendlight.vfp,
// so don't call assert (through verify) here until it's fixed (if fixable)
// else the game crashes on linux when using debug builds
// FIXME: fix this properly if possible?
// RB: yes but it would require an additional blend light skinned shader
//if( !verify( renderProgManager.ShaderUsesJoints() ) )
if( !renderProgManager.ShaderUsesJoints() )
// DG end
{
return;
}
}
else
{
if( !verify( !renderProgManager.ShaderUsesJoints() || renderProgManager.ShaderHasOptionalSkinning() ) )
{
return;
}
}
if( surf->jointCache )
{
idJointBuffer jointBuffer;
if( !vertexCache.GetJointBuffer( surf->jointCache, &jointBuffer ) )
{
idLib::Warning( "RB_DrawElementsWithCounters, jointBuffer == NULL" );
return;
}
assert( ( jointBuffer.GetOffset() & ( glConfig.uniformBufferOffsetAlignment - 1 ) ) == 0 );
// RB: 64 bit fixes, changed GLuint to GLintptr
const GLintptr ubo = reinterpret_cast< GLintptr >( jointBuffer.GetAPIObject() );
// RB end
glBindBufferRange( GL_UNIFORM_BUFFER, 0, ubo, jointBuffer.GetOffset(), jointBuffer.GetNumJoints() * sizeof( idJointMat ) );
}
renderProgManager.CommitUniforms();
// RB: 64 bit fixes, changed GLuint to GLintptr
if( currentIndexBuffer != ( GLintptr )indexBuffer->GetAPIObject() || !r_useStateCaching.GetBool() )
{
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ( GLintptr )indexBuffer->GetAPIObject() );
currentIndexBuffer = ( GLintptr )indexBuffer->GetAPIObject();
}
if( ( vertexLayout != LAYOUT_DRAW_VERT ) || ( currentVertexBuffer != ( GLintptr )vertexBuffer->GetAPIObject() ) || !r_useStateCaching.GetBool() )
{
glBindBuffer( GL_ARRAY_BUFFER, ( GLintptr )vertexBuffer->GetAPIObject() );
backEnd.glState.currentVertexBuffer = ( GLintptr )vertexBuffer->GetAPIObject();
glEnableVertexAttribArray( PC_ATTRIB_INDEX_VERTEX );
glEnableVertexAttribArray( PC_ATTRIB_INDEX_NORMAL );
glEnableVertexAttribArray( PC_ATTRIB_INDEX_COLOR );
glEnableVertexAttribArray( PC_ATTRIB_INDEX_COLOR2 );
glEnableVertexAttribArray( PC_ATTRIB_INDEX_ST );
glEnableVertexAttribArray( PC_ATTRIB_INDEX_TANGENT );
#if defined(USE_GLES2) || defined(USE_GLES3)
glVertexAttribPointer( PC_ATTRIB_INDEX_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_XYZ_OFFSET ) );
glVertexAttribPointer( PC_ATTRIB_INDEX_NORMAL, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_NORMAL_OFFSET ) );
glVertexAttribPointer( PC_ATTRIB_INDEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_COLOR_OFFSET ) );
glVertexAttribPointer( PC_ATTRIB_INDEX_COLOR2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_COLOR2_OFFSET ) );
#if defined(USE_ANGLE)
glVertexAttribPointer( PC_ATTRIB_INDEX_ST, 2, GL_HALF_FLOAT_OES, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_ST_OFFSET ) );
#else
glVertexAttribPointer( PC_ATTRIB_INDEX_ST, 2, GL_HALF_FLOAT, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_ST_OFFSET ) );
#endif
glVertexAttribPointer( PC_ATTRIB_INDEX_TANGENT, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( vertOffset + DRAWVERT_TANGENT_OFFSET ) );
#else
glVertexAttribPointer( PC_ATTRIB_INDEX_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof( idDrawVert ), ( void* )( DRAWVERT_XYZ_OFFSET ) );
glVertexAttribPointer( PC_ATTRIB_INDEX_NORMAL, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_NORMAL_OFFSET ) );
glVertexAttribPointer( PC_ATTRIB_INDEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_COLOR_OFFSET ) );
glVertexAttribPointer( PC_ATTRIB_INDEX_COLOR2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_COLOR2_OFFSET ) );
glVertexAttribPointer( PC_ATTRIB_INDEX_ST, 2, GL_HALF_FLOAT, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_ST_OFFSET ) );
glVertexAttribPointer( PC_ATTRIB_INDEX_TANGENT, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( idDrawVert ), ( void* )( DRAWVERT_TANGENT_OFFSET ) );
#endif // #if defined(USE_GLES2) || defined(USE_GLES3)
backEnd.glState.vertexLayout = LAYOUT_DRAW_VERT;
}
// RB end
#if defined(USE_GLES3) //defined(USE_GLES2)
glDrawElements( GL_TRIANGLES,
r_singleTriangle.GetBool() ? 3 : surf->numIndexes,
GL_INDEX_TYPE,
( triIndex_t* )indexOffset );
#else
glDrawElementsBaseVertex( GL_TRIANGLES,
r_singleTriangle.GetBool() ? 3 : surf->numIndexes,
GL_INDEX_TYPE,
( triIndex_t* )indexOffset,
vertOffset / sizeof( idDrawVert ) );
#endif
// RB: added stats
backEnd.pc.c_drawElements++;
backEnd.pc.c_drawIndexes += surf->numIndexes;
// RB end
}
/*
=========================================================================================================
GL COMMANDS
=========================================================================================================
*/
/*
==================
idRenderBackend::GL_StartFrame
==================
*/
void idRenderBackend::GL_StartFrame()
{
}
/*
==================
idRenderBackend::GL_EndFrame
==================
*/
void idRenderBackend::GL_EndFrame()
{
// Fix for the steam overlay not showing up while in game without Shell/Debug/Console/Menu also rendering
glColorMask( 1, 1, 1, 1 );
glFlush();
}
/*
========================
GL_SetDefaultState
This should initialize all GL state that any part of the entire program
may touch, including the editor.
========================
*/
void idRenderBackend::GL_SetDefaultState()
{
RENDERLOG_PRINTF( "--- GL_SetDefaultState ---\n" );
glClearDepth( 1.0f );
// make sure our GL state vector is set correctly
memset( &glcontext.tmu, 0, sizeof( glcontext.tmu ) );
currenttmu = 0;
currentVertexBuffer = 0;
currentIndexBuffer = 0;
currentFramebuffer = 0;
faceCulling = 0;
vertexLayout = LAYOUT_UNKNOWN;
polyOfsScale = 0.0f;
polyOfsBias = 0.0f;
glStateBits = 0;
hdrAverageLuminance = 0;
hdrMaxLuminance = 0;
hdrTime = 0;
hdrKey = 0;
GL_State( 0, true );
// RB begin
Framebuffer::Unbind();
// RB end
// These are changed by GL_Cull
glCullFace( GL_FRONT_AND_BACK );
glEnable( GL_CULL_FACE );
// These are changed by GL_State
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
glBlendFunc( GL_ONE, GL_ZERO );
glDepthMask( GL_TRUE );
glDepthFunc( GL_LESS );
glDisable( GL_STENCIL_TEST );
glDisable( GL_POLYGON_OFFSET_FILL );
glDisable( GL_POLYGON_OFFSET_LINE );
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
// These should never be changed
// DG: deprecated in opengl 3.2 and not needed because we don't do fixed function pipeline
// glShadeModel( GL_SMOOTH );
// DG end
glEnable( GL_DEPTH_TEST );
glEnable( GL_BLEND );
glEnable( GL_SCISSOR_TEST );
glDrawBuffer( GL_BACK );
glReadBuffer( GL_BACK );
if( r_useScissor.GetBool() )
{
glScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() );
}
// RB: don't keep renderprogs that were enabled during level load
renderProgManager.Unbind();
// RB end
}
/*
====================
idRenderBackend::GL_State
This routine is responsible for setting the most commonly changed state
====================
*/
void idRenderBackend::GL_State( uint64 stateBits, bool forceGlState )
{
uint64 diff = stateBits ^ glStateBits;
if( !r_useStateCaching.GetBool() || forceGlState )
{
// make sure everything is set all the time, so we
// can see if our delta checking is screwing up
diff = 0xFFFFFFFFFFFFFFFF;
}
else if( diff == 0 )
{
return;
}
//
// check depthFunc bits
//
if( diff & GLS_DEPTHFUNC_BITS )
{
switch( stateBits & GLS_DEPTHFUNC_BITS )
{
case GLS_DEPTHFUNC_EQUAL:
glDepthFunc( GL_EQUAL );
break;
case GLS_DEPTHFUNC_ALWAYS:
glDepthFunc( GL_ALWAYS );
break;
case GLS_DEPTHFUNC_LESS:
glDepthFunc( GL_LEQUAL );
break;
case GLS_DEPTHFUNC_GREATER:
glDepthFunc( GL_GEQUAL );
break;
}
}
//
// check blend bits
//
if( diff & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) )
{
GLenum srcFactor = GL_ONE;
GLenum dstFactor = GL_ZERO;
switch( stateBits & GLS_SRCBLEND_BITS )
{
case GLS_SRCBLEND_ZERO:
srcFactor = GL_ZERO;
break;
case GLS_SRCBLEND_ONE:
srcFactor = GL_ONE;
break;
case GLS_SRCBLEND_DST_COLOR:
srcFactor = GL_DST_COLOR;
break;
case GLS_SRCBLEND_ONE_MINUS_DST_COLOR:
srcFactor = GL_ONE_MINUS_DST_COLOR;
break;
case GLS_SRCBLEND_SRC_ALPHA:
srcFactor = GL_SRC_ALPHA;
break;
case GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA:
srcFactor = GL_ONE_MINUS_SRC_ALPHA;
break;
case GLS_SRCBLEND_DST_ALPHA:
srcFactor = GL_DST_ALPHA;
break;
case GLS_SRCBLEND_ONE_MINUS_DST_ALPHA:
srcFactor = GL_ONE_MINUS_DST_ALPHA;
break;
default:
assert( !"GL_State: invalid src blend state bits\n" );
break;
}
switch( stateBits & GLS_DSTBLEND_BITS )
{
case GLS_DSTBLEND_ZERO:
dstFactor = GL_ZERO;
break;
case GLS_DSTBLEND_ONE:
dstFactor = GL_ONE;
break;
case GLS_DSTBLEND_SRC_COLOR:
dstFactor = GL_SRC_COLOR;
break;
case GLS_DSTBLEND_ONE_MINUS_SRC_COLOR:
dstFactor = GL_ONE_MINUS_SRC_COLOR;
break;
case GLS_DSTBLEND_SRC_ALPHA:
dstFactor = GL_SRC_ALPHA;
break;
case GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA:
dstFactor = GL_ONE_MINUS_SRC_ALPHA;
break;
case GLS_DSTBLEND_DST_ALPHA:
dstFactor = GL_DST_ALPHA;
break;
case GLS_DSTBLEND_ONE_MINUS_DST_ALPHA:
dstFactor = GL_ONE_MINUS_DST_ALPHA;
break;
default:
assert( !"GL_State: invalid dst blend state bits\n" );
break;
}
// Only actually update GL's blend func if blending is enabled.
if( srcFactor == GL_ONE && dstFactor == GL_ZERO )
{
glDisable( GL_BLEND );
}
else
{
glEnable( GL_BLEND );
glBlendFunc( srcFactor, dstFactor );
}
}
//
// check depthmask
//
if( diff & GLS_DEPTHMASK )
{
if( stateBits & GLS_DEPTHMASK )
{
glDepthMask( GL_FALSE );
}
else
{
glDepthMask( GL_TRUE );
}
}
//
// check colormask
//
if( diff & ( GLS_REDMASK | GLS_GREENMASK | GLS_BLUEMASK | GLS_ALPHAMASK ) )
{
GLboolean r = ( stateBits & GLS_REDMASK ) ? GL_FALSE : GL_TRUE;
GLboolean g = ( stateBits & GLS_GREENMASK ) ? GL_FALSE : GL_TRUE;
GLboolean b = ( stateBits & GLS_BLUEMASK ) ? GL_FALSE : GL_TRUE;
GLboolean a = ( stateBits & GLS_ALPHAMASK ) ? GL_FALSE : GL_TRUE;
glColorMask( r, g, b, a );
}
//
// fill/line mode
//
if( diff & GLS_POLYMODE_LINE )
{
if( stateBits & GLS_POLYMODE_LINE )
{
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
}
else
{
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
}
}
//
// polygon offset
//
if( diff & GLS_POLYGON_OFFSET )
{
if( stateBits & GLS_POLYGON_OFFSET )
{
glPolygonOffset( polyOfsScale, polyOfsBias );
glEnable( GL_POLYGON_OFFSET_FILL );
glEnable( GL_POLYGON_OFFSET_LINE );
}
else
{
glDisable( GL_POLYGON_OFFSET_FILL );
glDisable( GL_POLYGON_OFFSET_LINE );
}
}
#if !defined( USE_CORE_PROFILE )
//
// alpha test
//
if( diff & ( GLS_ALPHATEST_FUNC_BITS | GLS_ALPHATEST_FUNC_REF_BITS ) )
{
if( ( stateBits & GLS_ALPHATEST_FUNC_BITS ) != 0 )
{
glEnable( GL_ALPHA_TEST );
GLenum func = GL_ALWAYS;
switch( stateBits & GLS_ALPHATEST_FUNC_BITS )
{
case GLS_ALPHATEST_FUNC_LESS:
func = GL_LESS;
break;
case GLS_ALPHATEST_FUNC_EQUAL:
func = GL_EQUAL;
break;
case GLS_ALPHATEST_FUNC_GREATER:
func = GL_GEQUAL;
break;
default:
assert( false );
}
GLclampf ref = ( ( stateBits & GLS_ALPHATEST_FUNC_REF_BITS ) >> GLS_ALPHATEST_FUNC_REF_SHIFT ) / ( float )0xFF;
glAlphaFunc( func, ref );
}
else
{
glDisable( GL_ALPHA_TEST );
}
}
#endif
//
// stencil
//
if( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) )
{
if( ( stateBits & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) ) != 0 )
{
glEnable( GL_STENCIL_TEST );
}
else
{
glDisable( GL_STENCIL_TEST );
}
}
if( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_FUNC_REF_BITS | GLS_STENCIL_FUNC_MASK_BITS ) )
{
GLuint ref = GLuint( ( stateBits & GLS_STENCIL_FUNC_REF_BITS ) >> GLS_STENCIL_FUNC_REF_SHIFT );
GLuint mask = GLuint( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT );
GLenum func = 0;
switch( stateBits & GLS_STENCIL_FUNC_BITS )
{
case GLS_STENCIL_FUNC_NEVER:
func = GL_NEVER;
break;
case GLS_STENCIL_FUNC_LESS:
func = GL_LESS;
break;
case GLS_STENCIL_FUNC_EQUAL:
func = GL_EQUAL;
break;
case GLS_STENCIL_FUNC_LEQUAL:
func = GL_LEQUAL;
break;
case GLS_STENCIL_FUNC_GREATER:
func = GL_GREATER;
break;
case GLS_STENCIL_FUNC_NOTEQUAL:
func = GL_NOTEQUAL;
break;
case GLS_STENCIL_FUNC_GEQUAL:
func = GL_GEQUAL;
break;
case GLS_STENCIL_FUNC_ALWAYS:
func = GL_ALWAYS;
break;
}
glStencilFunc( func, ref, mask );
}
if( diff & ( GLS_STENCIL_OP_FAIL_BITS | GLS_STENCIL_OP_ZFAIL_BITS | GLS_STENCIL_OP_PASS_BITS ) )
{
GLenum sFail = 0;
GLenum zFail = 0;
GLenum pass = 0;
switch( stateBits & GLS_STENCIL_OP_FAIL_BITS )
{
case GLS_STENCIL_OP_FAIL_KEEP:
sFail = GL_KEEP;
break;
case GLS_STENCIL_OP_FAIL_ZERO:
sFail = GL_ZERO;
break;
case GLS_STENCIL_OP_FAIL_REPLACE:
sFail = GL_REPLACE;
break;
case GLS_STENCIL_OP_FAIL_INCR:
sFail = GL_INCR;
break;
case GLS_STENCIL_OP_FAIL_DECR:
sFail = GL_DECR;
break;
case GLS_STENCIL_OP_FAIL_INVERT:
sFail = GL_INVERT;
break;
case GLS_STENCIL_OP_FAIL_INCR_WRAP:
sFail = GL_INCR_WRAP;
break;
case GLS_STENCIL_OP_FAIL_DECR_WRAP:
sFail = GL_DECR_WRAP;
break;
}
switch( stateBits & GLS_STENCIL_OP_ZFAIL_BITS )
{
case GLS_STENCIL_OP_ZFAIL_KEEP:
zFail = GL_KEEP;
break;
case GLS_STENCIL_OP_ZFAIL_ZERO:
zFail = GL_ZERO;
break;
case GLS_STENCIL_OP_ZFAIL_REPLACE:
zFail = GL_REPLACE;
break;
case GLS_STENCIL_OP_ZFAIL_INCR:
zFail = GL_INCR;
break;
case GLS_STENCIL_OP_ZFAIL_DECR:
zFail = GL_DECR;
break;
case GLS_STENCIL_OP_ZFAIL_INVERT:
zFail = GL_INVERT;
break;
case GLS_STENCIL_OP_ZFAIL_INCR_WRAP:
zFail = GL_INCR_WRAP;
break;
case GLS_STENCIL_OP_ZFAIL_DECR_WRAP:
zFail = GL_DECR_WRAP;
break;
}
switch( stateBits & GLS_STENCIL_OP_PASS_BITS )
{
case GLS_STENCIL_OP_PASS_KEEP:
pass = GL_KEEP;
break;
case GLS_STENCIL_OP_PASS_ZERO:
pass = GL_ZERO;
break;
case GLS_STENCIL_OP_PASS_REPLACE:
pass = GL_REPLACE;
break;
case GLS_STENCIL_OP_PASS_INCR:
pass = GL_INCR;
break;
case GLS_STENCIL_OP_PASS_DECR:
pass = GL_DECR;
break;
case GLS_STENCIL_OP_PASS_INVERT:
pass = GL_INVERT;
break;
case GLS_STENCIL_OP_PASS_INCR_WRAP:
pass = GL_INCR_WRAP;
break;
case GLS_STENCIL_OP_PASS_DECR_WRAP:
pass = GL_DECR_WRAP;
break;
}
glStencilOp( sFail, zFail, pass );
}
glStateBits = stateBits;
}
/*
====================
idRenderBackend::SelectTexture
====================
*/
void idRenderBackend::GL_SelectTexture( int unit )
{
if( currenttmu == unit )
{
return;
}
if( unit < 0 || unit >= glConfig.maxTextureImageUnits )
{
common->Warning( "GL_SelectTexture: unit = %i", unit );
return;
}
RENDERLOG_PRINTF( "GL_SelectTexture( %i );\n", unit );
currenttmu = unit;
}
/*
============================================================================
@ -62,10 +709,10 @@ RENDER BACK END THREAD FUNCTIONS
/*
=============
RB_DrawFlickerBox
idRenderBackend::DrawFlickerBox
=============
*/
static void RB_DrawFlickerBox()
void idRenderBackend::DrawFlickerBox()
{
if( !r_drawFlickerBox.GetBool() )
{
@ -85,10 +732,10 @@ static void RB_DrawFlickerBox()
/*
=============
RB_SetBuffer
idRenderBackend::SetBuffer
=============
*/
static void RB_SetBuffer( const void* data )
void idRenderBackend::SetBuffer( const void* data )
{
// see which draw buffer we want to render the frame to
@ -130,7 +777,7 @@ GL_BlockingSwapBuffers
We want to exit this with the GPU idle, right at vsync
=============
*/
const void GL_BlockingSwapBuffers()
void idRenderBackend::BlockingSwapBuffers()
{
RENDERLOG_PRINTF( "***************** GL_BlockingSwapBuffers *****************\n\n\n" );
@ -211,6 +858,32 @@ const void GL_BlockingSwapBuffers()
prevBlockTime = exitBlockTime;
}
/*
=============
idRenderBackend::idRenderBackend
=============
*/
idRenderBackend::idRenderBackend()
{
memset( gammaTable, 0, sizeof( gammaTable ) );
glcontext.bAnisotropicFilterAvailable = false;
glcontext.bTextureLODBiasAvailable = false;
memset( glcontext.tmu, 0, sizeof( glcontext.tmu ) );
memset( glcontext.stencilOperations, 0, sizeof( glcontext.stencilOperations ) );
}
/*
=============
idRenderBackend::~idRenderBackend
=============
*/
idRenderBackend::~idRenderBackend()
{
}
/*
====================
R_MakeStereoRenderImage
@ -228,12 +901,12 @@ static void R_MakeStereoRenderImage( idImage* image )
/*
====================
RB_StereoRenderExecuteBackEndCommands
idRenderBackend::StereoRenderExecuteBackEndCommands
Renders the draw list twice, with slight modifications for left eye / right eye
====================
*/
void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds )
void idRenderBackend::StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds )
{
uint64 backEndStartTime = Sys_Microseconds();
@ -309,7 +982,7 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds
}
break;
case RC_SET_BUFFER:
RB_SetBuffer( cmds );
SetBuffer( cmds );
break;
case RC_COPY_RENDER:
RB_CopyRender( cmds );
@ -376,16 +1049,16 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds
stereoRenderImages[1]->Bind();
GL_SelectTexture( 1 );
stereoRenderImages[0]->Bind();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
DrawElementsWithCounters( &unitSquareSurface );
glDrawBuffer( GL_BACK_LEFT );
GL_SelectTexture( 1 );
stereoRenderImages[1]->Bind();
GL_SelectTexture( 0 );
stereoRenderImages[0]->Bind();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
RB_DrawElementsWithCounters( &unitSquareSurface );
break;
case STEREO3D_HDMI_720:
// HDMI 720P 3D
GL_SelectTexture( 0 );
@ -393,19 +1066,20 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds
GL_SelectTexture( 1 );
stereoRenderImages[0]->Bind();
GL_ViewportAndScissor( 0, 0, 1280, 720 );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
DrawElementsWithCounters( &unitSquareSurface );
GL_SelectTexture( 0 );
stereoRenderImages[0]->Bind();
GL_SelectTexture( 1 );
stereoRenderImages[1]->Bind();
GL_ViewportAndScissor( 0, 750, 1280, 720 );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
DrawElementsWithCounters( &unitSquareSurface );
// force the HDMI 720P 3D guard band to a constant color
glScissor( 0, 720, 1280, 30 );
glClear( GL_COLOR_BUFFER_BIT );
break;
default:
case STEREO3D_SIDE_BY_SIDE:
if( stereoRender_warp.GetBool() )
@ -443,7 +1117,7 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds
stereoRenderImages[0]->Bind();
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
DrawElementsWithCounters( &unitSquareSurface );
idVec4 color2( stereoRender_warpCenterX.GetFloat(), stereoRender_warpCenterY.GetFloat(), stereoRender_warpParmZ.GetFloat(), stereoRender_warpParmW.GetFloat() );
// don't use GL_Color(), because we don't want to clamp
@ -458,9 +1132,10 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds
stereoRenderImages[1]->Bind();
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
DrawElementsWithCounters( &unitSquareSurface );
break;
}
// a non-warped side-by-side-uncompressed (dual input cable) is rendered
// just like STEREO3D_SIDE_BY_SIDE_COMPRESSED, so fall through.
case STEREO3D_SIDE_BY_SIDE_COMPRESSED:
@ -469,14 +1144,14 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds
GL_SelectTexture( 1 );
stereoRenderImages[1]->Bind();
GL_ViewportAndScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
DrawElementsWithCounters( &unitSquareSurface );
GL_SelectTexture( 0 );
stereoRenderImages[1]->Bind();
GL_SelectTexture( 1 );
stereoRenderImages[0]->Bind();
GL_ViewportAndScissor( renderSystem->GetWidth(), 0, renderSystem->GetWidth(), renderSystem->GetHeight() );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
DrawElementsWithCounters( &unitSquareSurface );
break;
case STEREO3D_TOP_AND_BOTTOM_COMPRESSED:
@ -485,14 +1160,14 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds
GL_SelectTexture( 0 );
stereoRenderImages[1]->Bind();
GL_ViewportAndScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
DrawElementsWithCounters( &unitSquareSurface );
GL_SelectTexture( 1 );
stereoRenderImages[1]->Bind();
GL_SelectTexture( 0 );
stereoRenderImages[0]->Bind();
GL_ViewportAndScissor( 0, renderSystem->GetHeight(), renderSystem->GetWidth(), renderSystem->GetHeight() );
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
DrawElementsWithCounters( &unitSquareSurface );
break;
case STEREO3D_INTERLACED:
@ -509,7 +1184,7 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds
GL_ViewportAndScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() * 2 );
renderProgManager.BindShader_StereoInterlace();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
RB_DrawElementsWithCounters( &unitSquareSurface );
GL_SelectTexture( 0 );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
@ -523,7 +1198,7 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds
}
// debug tool
RB_DrawFlickerBox();
DrawFlickerBox();
// make sure the drawing is actually started
glFlush();
@ -532,7 +1207,7 @@ void RB_StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds
// stop rendering on this thread
uint64 backEndFinishTime = Sys_Microseconds();
backEnd.pc.totalMicroSec = backEndFinishTime - backEndStartTime;
pc.totalMicroSec = backEndFinishTime - backEndStartTime;
}
/*
@ -543,7 +1218,7 @@ This function will be called syncronously if running without
smp extensions, or asyncronously by another thread.
====================
*/
void RB_ExecuteBackEndCommands( const emptyCommand_t* cmds )
void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds )
{
// r_debugRenderToTexture
int c_draw3d = 0;
@ -562,7 +1237,7 @@ void RB_ExecuteBackEndCommands( const emptyCommand_t* cmds )
if( renderSystem->GetStereo3DMode() != STEREO3D_OFF )
{
RB_StereoRenderExecuteBackEndCommands( cmds );
StereoRenderExecuteBackEndCommands( cmds );
renderLog.EndFrame();
return;
}
@ -612,7 +1287,7 @@ void RB_ExecuteBackEndCommands( const emptyCommand_t* cmds )
}
}
RB_DrawFlickerBox();
DrawFlickerBox();
// Fix for the steam overlay not showing up while in game without Shell/Debug/Console/Menu also rendering
glColorMask( 1, 1, 1, 1 );
@ -621,7 +1296,7 @@ void RB_ExecuteBackEndCommands( const emptyCommand_t* cmds )
// stop rendering on this thread
uint64 backEndFinishTime = Sys_Microseconds();
backEnd.pc.totalMicroSec = backEndFinishTime - backEndStartTime;
pc.totalMicroSec = backEndFinishTime - backEndStartTime;
if( r_debugRenderToTexture.GetInteger() == 1 )
{

View file

@ -32,28 +32,7 @@ If you have questions concerning this license or the applicable additional terms
#include "../RenderCommon.h"
/*
====================
GL_SelectTexture
====================
*/
void GL_SelectTexture( int unit )
{
if( backEnd.glState.currenttmu == unit )
{
return;
}
if( unit < 0 || unit >= glConfig.maxTextureImageUnits )
{
common->Warning( "GL_SelectTexture: unit = %i", unit );
return;
}
RENDERLOG_PRINTF( "GL_SelectTexture( %i );\n", unit );
backEnd.glState.currenttmu = unit;
}
/*
====================
@ -65,7 +44,7 @@ rendered is a mirored view.
*/
void GL_Cull( int cullType )
{
if( backEnd.glState.faceCulling == cullType )
if( tr.backend.faceCulling == cullType )
{
return;
}
@ -76,7 +55,7 @@ void GL_Cull( int cullType )
}
else
{
if( backEnd.glState.faceCulling == CT_TWO_SIDED )
if( tr.backend.faceCulling == CT_TWO_SIDED )
{
glEnable( GL_CULL_FACE );
}
@ -105,7 +84,7 @@ void GL_Cull( int cullType )
}
}
backEnd.glState.faceCulling = cullType;
tr.backend.faceCulling = cullType;
}
/*
@ -135,9 +114,9 @@ GL_PolygonOffset
*/
void GL_PolygonOffset( float scale, float bias )
{
backEnd.glState.polyOfsScale = scale;
backEnd.glState.polyOfsBias = bias;
if( backEnd.glState.glStateBits & GLS_POLYGON_OFFSET )
tr.backend.polyOfsScale = scale;
tr.backend.polyOfsBias = bias;
if( tr.backend.glStateBits & GLS_POLYGON_OFFSET )
{
glPolygonOffset( scale, bias );
}
@ -211,15 +190,7 @@ void GL_Color( float* color )
*/
// RB begin
void GL_Color( const idVec3& color )
{
GL_Color( color[0], color[1], color[2], 1.0f );
}
void GL_Color( const idVec4& color )
{
GL_Color( color[0], color[1], color[2], color[3] );
}
// RB end
/*
@ -287,424 +258,8 @@ void GL_Clear( bool color, bool depth, bool stencil, byte stencilValue, float r,
// RB end
}
/*
========================
GL_SetDefaultState
This should initialize all GL state that any part of the entire program
may touch, including the editor.
========================
*/
void GL_SetDefaultState()
{
RENDERLOG_PRINTF( "--- GL_SetDefaultState ---\n" );
glClearDepth( 1.0f );
// make sure our GL state vector is set correctly
memset( &backEnd.glState, 0, sizeof( backEnd.glState ) );
GL_State( 0, true );
// RB begin
Framebuffer::Unbind();
// RB end
// These are changed by GL_Cull
glCullFace( GL_FRONT_AND_BACK );
glEnable( GL_CULL_FACE );
// These are changed by GL_State
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
glBlendFunc( GL_ONE, GL_ZERO );
glDepthMask( GL_TRUE );
glDepthFunc( GL_LESS );
glDisable( GL_STENCIL_TEST );
glDisable( GL_POLYGON_OFFSET_FILL );
glDisable( GL_POLYGON_OFFSET_LINE );
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
// These should never be changed
// DG: deprecated in opengl 3.2 and not needed because we don't do fixed function pipeline
// glShadeModel( GL_SMOOTH );
// DG end
glEnable( GL_DEPTH_TEST );
glEnable( GL_BLEND );
glEnable( GL_SCISSOR_TEST );
glDrawBuffer( GL_BACK );
glReadBuffer( GL_BACK );
if( r_useScissor.GetBool() )
{
glScissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() );
}
// RB: don't keep renderprogs that were enabled during level load
renderProgManager.Unbind();
// RB end
}
/*
====================
GL_State
This routine is responsible for setting the most commonly changed state
====================
*/
void GL_State( uint64 stateBits, bool forceGlState )
{
uint64 diff = stateBits ^ backEnd.glState.glStateBits;
if( !r_useStateCaching.GetBool() || forceGlState )
{
// make sure everything is set all the time, so we
// can see if our delta checking is screwing up
diff = 0xFFFFFFFFFFFFFFFF;
}
else if( diff == 0 )
{
return;
}
//
// check depthFunc bits
//
if( diff & GLS_DEPTHFUNC_BITS )
{
switch( stateBits & GLS_DEPTHFUNC_BITS )
{
case GLS_DEPTHFUNC_EQUAL:
glDepthFunc( GL_EQUAL );
break;
case GLS_DEPTHFUNC_ALWAYS:
glDepthFunc( GL_ALWAYS );
break;
case GLS_DEPTHFUNC_LESS:
glDepthFunc( GL_LEQUAL );
break;
case GLS_DEPTHFUNC_GREATER:
glDepthFunc( GL_GEQUAL );
break;
}
}
//
// check blend bits
//
if( diff & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) )
{
GLenum srcFactor = GL_ONE;
GLenum dstFactor = GL_ZERO;
switch( stateBits & GLS_SRCBLEND_BITS )
{
case GLS_SRCBLEND_ZERO:
srcFactor = GL_ZERO;
break;
case GLS_SRCBLEND_ONE:
srcFactor = GL_ONE;
break;
case GLS_SRCBLEND_DST_COLOR:
srcFactor = GL_DST_COLOR;
break;
case GLS_SRCBLEND_ONE_MINUS_DST_COLOR:
srcFactor = GL_ONE_MINUS_DST_COLOR;
break;
case GLS_SRCBLEND_SRC_ALPHA:
srcFactor = GL_SRC_ALPHA;
break;
case GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA:
srcFactor = GL_ONE_MINUS_SRC_ALPHA;
break;
case GLS_SRCBLEND_DST_ALPHA:
srcFactor = GL_DST_ALPHA;
break;
case GLS_SRCBLEND_ONE_MINUS_DST_ALPHA:
srcFactor = GL_ONE_MINUS_DST_ALPHA;
break;
default:
assert( !"GL_State: invalid src blend state bits\n" );
break;
}
switch( stateBits & GLS_DSTBLEND_BITS )
{
case GLS_DSTBLEND_ZERO:
dstFactor = GL_ZERO;
break;
case GLS_DSTBLEND_ONE:
dstFactor = GL_ONE;
break;
case GLS_DSTBLEND_SRC_COLOR:
dstFactor = GL_SRC_COLOR;
break;
case GLS_DSTBLEND_ONE_MINUS_SRC_COLOR:
dstFactor = GL_ONE_MINUS_SRC_COLOR;
break;
case GLS_DSTBLEND_SRC_ALPHA:
dstFactor = GL_SRC_ALPHA;
break;
case GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA:
dstFactor = GL_ONE_MINUS_SRC_ALPHA;
break;
case GLS_DSTBLEND_DST_ALPHA:
dstFactor = GL_DST_ALPHA;
break;
case GLS_DSTBLEND_ONE_MINUS_DST_ALPHA:
dstFactor = GL_ONE_MINUS_DST_ALPHA;
break;
default:
assert( !"GL_State: invalid dst blend state bits\n" );
break;
}
// Only actually update GL's blend func if blending is enabled.
if( srcFactor == GL_ONE && dstFactor == GL_ZERO )
{
glDisable( GL_BLEND );
}
else
{
glEnable( GL_BLEND );
glBlendFunc( srcFactor, dstFactor );
}
}
//
// check depthmask
//
if( diff & GLS_DEPTHMASK )
{
if( stateBits & GLS_DEPTHMASK )
{
glDepthMask( GL_FALSE );
}
else
{
glDepthMask( GL_TRUE );
}
}
//
// check colormask
//
if( diff & ( GLS_REDMASK | GLS_GREENMASK | GLS_BLUEMASK | GLS_ALPHAMASK ) )
{
GLboolean r = ( stateBits & GLS_REDMASK ) ? GL_FALSE : GL_TRUE;
GLboolean g = ( stateBits & GLS_GREENMASK ) ? GL_FALSE : GL_TRUE;
GLboolean b = ( stateBits & GLS_BLUEMASK ) ? GL_FALSE : GL_TRUE;
GLboolean a = ( stateBits & GLS_ALPHAMASK ) ? GL_FALSE : GL_TRUE;
glColorMask( r, g, b, a );
}
//
// fill/line mode
//
if( diff & GLS_POLYMODE_LINE )
{
if( stateBits & GLS_POLYMODE_LINE )
{
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
}
else
{
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
}
}
//
// polygon offset
//
if( diff & GLS_POLYGON_OFFSET )
{
if( stateBits & GLS_POLYGON_OFFSET )
{
glPolygonOffset( backEnd.glState.polyOfsScale, backEnd.glState.polyOfsBias );
glEnable( GL_POLYGON_OFFSET_FILL );
glEnable( GL_POLYGON_OFFSET_LINE );
}
else
{
glDisable( GL_POLYGON_OFFSET_FILL );
glDisable( GL_POLYGON_OFFSET_LINE );
}
}
#if !defined( USE_CORE_PROFILE )
//
// alpha test
//
if( diff & ( GLS_ALPHATEST_FUNC_BITS | GLS_ALPHATEST_FUNC_REF_BITS ) )
{
if( ( stateBits & GLS_ALPHATEST_FUNC_BITS ) != 0 )
{
glEnable( GL_ALPHA_TEST );
GLenum func = GL_ALWAYS;
switch( stateBits & GLS_ALPHATEST_FUNC_BITS )
{
case GLS_ALPHATEST_FUNC_LESS:
func = GL_LESS;
break;
case GLS_ALPHATEST_FUNC_EQUAL:
func = GL_EQUAL;
break;
case GLS_ALPHATEST_FUNC_GREATER:
func = GL_GEQUAL;
break;
default:
assert( false );
}
GLclampf ref = ( ( stateBits & GLS_ALPHATEST_FUNC_REF_BITS ) >> GLS_ALPHATEST_FUNC_REF_SHIFT ) / ( float )0xFF;
glAlphaFunc( func, ref );
}
else
{
glDisable( GL_ALPHA_TEST );
}
}
#endif
//
// stencil
//
if( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) )
{
if( ( stateBits & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) ) != 0 )
{
glEnable( GL_STENCIL_TEST );
}
else
{
glDisable( GL_STENCIL_TEST );
}
}
if( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_FUNC_REF_BITS | GLS_STENCIL_FUNC_MASK_BITS ) )
{
GLuint ref = GLuint( ( stateBits & GLS_STENCIL_FUNC_REF_BITS ) >> GLS_STENCIL_FUNC_REF_SHIFT );
GLuint mask = GLuint( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT );
GLenum func = 0;
switch( stateBits & GLS_STENCIL_FUNC_BITS )
{
case GLS_STENCIL_FUNC_NEVER:
func = GL_NEVER;
break;
case GLS_STENCIL_FUNC_LESS:
func = GL_LESS;
break;
case GLS_STENCIL_FUNC_EQUAL:
func = GL_EQUAL;
break;
case GLS_STENCIL_FUNC_LEQUAL:
func = GL_LEQUAL;
break;
case GLS_STENCIL_FUNC_GREATER:
func = GL_GREATER;
break;
case GLS_STENCIL_FUNC_NOTEQUAL:
func = GL_NOTEQUAL;
break;
case GLS_STENCIL_FUNC_GEQUAL:
func = GL_GEQUAL;
break;
case GLS_STENCIL_FUNC_ALWAYS:
func = GL_ALWAYS;
break;
}
glStencilFunc( func, ref, mask );
}
if( diff & ( GLS_STENCIL_OP_FAIL_BITS | GLS_STENCIL_OP_ZFAIL_BITS | GLS_STENCIL_OP_PASS_BITS ) )
{
GLenum sFail = 0;
GLenum zFail = 0;
GLenum pass = 0;
switch( stateBits & GLS_STENCIL_OP_FAIL_BITS )
{
case GLS_STENCIL_OP_FAIL_KEEP:
sFail = GL_KEEP;
break;
case GLS_STENCIL_OP_FAIL_ZERO:
sFail = GL_ZERO;
break;
case GLS_STENCIL_OP_FAIL_REPLACE:
sFail = GL_REPLACE;
break;
case GLS_STENCIL_OP_FAIL_INCR:
sFail = GL_INCR;
break;
case GLS_STENCIL_OP_FAIL_DECR:
sFail = GL_DECR;
break;
case GLS_STENCIL_OP_FAIL_INVERT:
sFail = GL_INVERT;
break;
case GLS_STENCIL_OP_FAIL_INCR_WRAP:
sFail = GL_INCR_WRAP;
break;
case GLS_STENCIL_OP_FAIL_DECR_WRAP:
sFail = GL_DECR_WRAP;
break;
}
switch( stateBits & GLS_STENCIL_OP_ZFAIL_BITS )
{
case GLS_STENCIL_OP_ZFAIL_KEEP:
zFail = GL_KEEP;
break;
case GLS_STENCIL_OP_ZFAIL_ZERO:
zFail = GL_ZERO;
break;
case GLS_STENCIL_OP_ZFAIL_REPLACE:
zFail = GL_REPLACE;
break;
case GLS_STENCIL_OP_ZFAIL_INCR:
zFail = GL_INCR;
break;
case GLS_STENCIL_OP_ZFAIL_DECR:
zFail = GL_DECR;
break;
case GLS_STENCIL_OP_ZFAIL_INVERT:
zFail = GL_INVERT;
break;
case GLS_STENCIL_OP_ZFAIL_INCR_WRAP:
zFail = GL_INCR_WRAP;
break;
case GLS_STENCIL_OP_ZFAIL_DECR_WRAP:
zFail = GL_DECR_WRAP;
break;
}
switch( stateBits & GLS_STENCIL_OP_PASS_BITS )
{
case GLS_STENCIL_OP_PASS_KEEP:
pass = GL_KEEP;
break;
case GLS_STENCIL_OP_PASS_ZERO:
pass = GL_ZERO;
break;
case GLS_STENCIL_OP_PASS_REPLACE:
pass = GL_REPLACE;
break;
case GLS_STENCIL_OP_PASS_INCR:
pass = GL_INCR;
break;
case GLS_STENCIL_OP_PASS_DECR:
pass = GL_DECR;
break;
case GLS_STENCIL_OP_PASS_INVERT:
pass = GL_INVERT;
break;
case GLS_STENCIL_OP_PASS_INCR_WRAP:
pass = GL_INCR_WRAP;
break;
case GLS_STENCIL_OP_PASS_DECR_WRAP:
pass = GL_DECR_WRAP;
break;
}
glStencilOp( sFail, zFail, pass );
}
backEnd.glState.glStateBits = stateBits;
}
/*
=================
@ -713,7 +268,7 @@ GL_GetCurrentState
*/
uint64 GL_GetCurrentState()
{
return backEnd.glState.glStateBits;
return tr.backend.glStateBits;
}
/*

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,468 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2016-2017 Dustin Land
Copyright (C) 2017 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#ifndef __RENDERER_BACKEND_H__
#define __RENDERER_BACKEND_H__
struct tmu_t
{
unsigned int current2DMap;
unsigned int current2DArray;
unsigned int currentCubeMap;
};
const int MAX_MULTITEXTURE_UNITS = 8;
enum stencilFace_t
{
STENCIL_FACE_FRONT,
STENCIL_FACE_BACK,
STENCIL_FACE_NUM
};
struct backEndCounters_t
{
int c_surfaces;
int c_shaders;
int c_drawElements;
int c_drawIndexes;
int c_shadowElements;
int c_shadowIndexes;
int c_copyFrameBuffer;
float c_overDraw;
int totalMicroSec; // total microseconds for backend run
int shadowMicroSec;
};
struct gfxImpParms_t
{
int x; // ignored in fullscreen
int y; // ignored in fullscreen
int width;
int height;
int fullScreen; // 0 = windowed, otherwise 1 based monitor number to go full screen on
// -1 = borderless window for spanning multiple displays
int displayHz;
int multiSamples;
};
#define MAX_DEBUG_LINES 16384
#define MAX_DEBUG_TEXT 512
#define MAX_DEBUG_POLYGONS 8192
struct debugLine_t
{
idVec4 rgb;
idVec3 start;
idVec3 end;
bool depthTest;
int lifeTime;
};
struct debugText_t
{
idStr text;
idVec3 origin;
float scale;
idVec4 color;
idMat3 viewAxis;
int align;
int lifeTime;
bool depthTest;
};
struct debugPolygon_t
{
idVec4 rgb;
idWinding winding;
bool depthTest;
int lifeTime;
};
void RB_SetMVP( const idRenderMatrix& mvp );
void RB_SetVertexColorParms( stageVertexColor_t svc );
void RB_GetShaderTextureMatrix( const float* shaderRegisters, const textureStage_t* texture, float matrix[16] );
void RB_LoadShaderTextureMatrix( const float* shaderRegisters, const textureStage_t* texture );
void RB_BakeTextureMatrixIntoTexgen( idPlane lightProject[3], const float* textureMatrix );
void RB_SetupInteractionStage( const shaderStage_t* surfaceStage, const float* surfaceRegs, const float lightColor[4], idVec4 matrix[2], float color[4] );
bool ChangeDisplaySettingsIfNeeded( gfxImpParms_t parms );
bool CreateGameWindow( gfxImpParms_t parms );
#if defined( ID_VULKAN )
struct gpuInfo_t
{
VkPhysicalDevice device;
VkPhysicalDeviceProperties props;
VkPhysicalDeviceMemoryProperties memProps;
VkSurfaceCapabilitiesKHR surfaceCaps;
idList< VkSurfaceFormatKHR > surfaceFormats;
idList< VkPresentModeKHR > presentModes;
idList< VkQueueFamilyProperties > queueFamilyProps;
idList< VkExtensionProperties > extensionProps;
};
struct vulkanContext_t
{
uint64 counter;
uint32 currentFrameData;
vertCacheHandle_t jointCacheHandle;
uint64 stencilOperations[ STENCIL_FACE_NUM ];
VkInstance instance;
VkPhysicalDevice physicalDevice;
VkPhysicalDeviceFeatures physicalDeviceFeatures;
VkDevice device;
VkQueue graphicsQueue;
VkQueue presentQueue;
int graphicsFamilyIdx;
int presentFamilyIdx;
VkDebugReportCallbackEXT callback;
idList< const char* > instanceExtensions;
idList< const char* > deviceExtensions;
idList< const char* > validationLayers;
gpuInfo_t* gpu;
idList< gpuInfo_t > gpus;
VkCommandPool commandPool;
idArray< VkCommandBuffer, NUM_FRAME_DATA > commandBuffer;
idArray< VkFence, NUM_FRAME_DATA > commandBufferFences;
idArray< bool, NUM_FRAME_DATA > commandBufferRecorded;
VkSurfaceKHR surface;
VkPresentModeKHR presentMode;
VkFormat depthFormat;
VkRenderPass renderPass;
VkPipelineCache pipelineCache;
VkSampleCountFlagBits sampleCount;
bool supersampling;
int fullscreen;
VkSwapchainKHR swapchain;
VkFormat swapchainFormat;
VkExtent2D swapchainExtent;
uint32 currentSwapIndex;
VkImage msaaImage;
VkImageView msaaImageView;
#if defined( ID_USE_AMD_ALLOCATOR )
VmaAllocation msaaVmaAllocation;
VmaAllocationInfo msaaAllocation;
#else
vulkanAllocation_t msaaAllocation;
#endif
idArray< idImage*, NUM_FRAME_DATA > swapchainImages;
idArray< VkFramebuffer, NUM_FRAME_DATA > frameBuffers;
idArray< VkSemaphore, NUM_FRAME_DATA > acquireSemaphores;
idArray< VkSemaphore, NUM_FRAME_DATA > renderCompleteSemaphores;
int currentImageParm;
idArray< idImage*, MAX_IMAGE_PARMS > imageParms;
};
extern vulkanContext_t vkcontext;
#else //if defined( ID_OPENGL )
struct glContext_t
{
bool bAnisotropicFilterAvailable;
bool bTextureLODBiasAvailable;
float maxTextureAnisotropy;
tmu_t tmu[ MAX_MULTITEXTURE_UNITS ];
uint64 stencilOperations[ STENCIL_FACE_NUM ];
};
extern glContext_t glcontext;
#endif
/*
===========================================================================
idRenderBackend
all state modified by the back end is separated from the front end state
===========================================================================
*/
class idRenderBackend
{
friend class Framebuffer;
public:
idRenderBackend();
~idRenderBackend();
void Init();
void Shutdown();
void ExecuteBackEndCommands( const emptyCommand_t* cmds );
void StereoRenderExecuteBackEndCommands( const emptyCommand_t* const allCmds );
void BlockingSwapBuffers();
void Print();
private:
void DrawFlickerBox();
void DrawElementsWithCounters( const drawSurf_t* surf );
void DrawStencilShadowPass( const drawSurf_t* drawSurf, const bool renderZPass );
void SetColorMappings();
void CheckCVars();
void ResizeImages();
void DrawViewInternal( const viewDef_t* viewDef, const int stereoEye );
void DrawView( const void* data, const int stereoEye );
void CopyRender( const void* data );
void BindVariableStageImage( const textureStage_t* texture, const float* shaderRegisters );
void PrepareStageTexturing( const shaderStage_t* pStage, const drawSurf_t* surf );
void FinishStageTexturing( const shaderStage_t* pStage, const drawSurf_t* surf );
void ResetViewportAndScissorToDefaultCamera( const viewDef_t* _viewDef );
void FillDepthBufferGeneric( const drawSurf_t* const* drawSurfs, int numDrawSurfs );
void FillDepthBufferFast( drawSurf_t** drawSurfs, int numDrawSurfs );
void T_BlendLight( const drawSurf_t* drawSurfs, const viewLight_t* vLight );
void BlendLight( const drawSurf_t* drawSurfs, const drawSurf_t* drawSurfs2, const viewLight_t* vLight );
void T_BasicFog( const drawSurf_t* drawSurfs, const idPlane fogPlanes[ 4 ], const idRenderMatrix* inverseBaseLightProject );
void FogPass( const drawSurf_t* drawSurfs, const drawSurf_t* drawSurfs2, const viewLight_t* vLight );
void FogAllLights();
void SetupInteractionStage( const shaderStage_t* surfaceStage, const float* surfaceRegs, const float lightColor[4],
idVec4 matrix[2], float color[4] );
void DrawInteractions( const viewDef_t* _viewDef );
void DrawSingleInteraction( drawInteraction_t* din );
int DrawShaderPasses( const drawSurf_t* const* const drawSurfs, const int numDrawSurfs,
const float guiStereoScreenOffset, const int stereoEye );
void RenderInteractions( const drawSurf_t* surfList, const viewLight_t* vLight, int depthFunc, bool performStencilTest, bool useLightDepthBounds );
// RB
void AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs, bool fillGbuffer );
void ShadowMapPass( const drawSurf_t* drawSurfs, const viewLight_t* vLight, int side );
void StencilShadowPass( const drawSurf_t* drawSurfs, const viewLight_t* vLight );
void StencilSelectLight( const viewLight_t* vLight );
// RB: HDR stuff
// TODO optimize and replace with compute shader
void CalculateAutomaticExposure();
void Tonemap( const viewDef_t* viewDef );
void Bloom( const viewDef_t* viewDef );
void DrawScreenSpaceAmbientOcclusion( const viewDef_t* _viewDef );
void DrawScreenSpaceGlobalIllumination( const viewDef_t* _viewDef );
// Experimental feature
void MotionBlur();
void PostProcess( const void* data );
private:
void GL_StartFrame();
void GL_EndFrame();
uint64 GL_GetCurrentStateMinusStencil() const;
void GL_SetDefaultState();
void GL_State( uint64 stateBits, bool forceGlState = false );
void GL_SeparateStencil( stencilFace_t face, uint64 stencilBits );
void GL_SelectTexture( int unit );
void GL_BindTexture( idImage* image );
void GL_CopyFrameBuffer( idImage* image, int x, int y, int imageWidth, int imageHeight );
void GL_CopyDepthBuffer( idImage* image, int x, int y, int imageWidth, int imageHeight );
// RB: HDR parm
void GL_Clear( bool color, bool depth, bool stencil, byte stencilValue, float r, float g, float b, float a, bool clearHDR = true );
void GL_DepthBoundsTest( const float zmin, const float zmax );
void GL_PolygonOffset( float scale, float bias );
void GL_Scissor( int x /* left*/, int y /* bottom */, int w, int h );
void GL_Viewport( int x /* left */, int y /* bottom */, int w, int h );
ID_INLINE void GL_Scissor( const idScreenRect& rect )
{
GL_Scissor( rect.x1, rect.y1, rect.x2 - rect.x1 + 1, rect.y2 - rect.y1 + 1 );
}
ID_INLINE void GL_Viewport( const idScreenRect& rect )
{
GL_Viewport( rect.x1, rect.y1, rect.x2 - rect.x1 + 1, rect.y2 - rect.y1 + 1 );
}
void GL_Color( float r, float g, float b, float a );
ID_INLINE void GL_Color( float r, float g, float b )
{
GL_Color( r, g, b, 1.0f );
}
ID_INLINE void GL_Color( const idVec3& color )
{
GL_Color( color[0], color[1], color[2], 1.0f );
}
ID_INLINE void GL_Color( const idVec4& color )
{
GL_Color( color[0], color[1], color[2], color[3] );
}
void GL_Color( float* color );
void SetBuffer( const void* data );
private:
void DBG_SimpleSurfaceSetup( const drawSurf_t* drawSurf );
void DBG_SimpleWorldSetup();
void DBG_ShowDestinationAlpha();
void DBG_ColorByStencilBuffer();
void DBG_ShowOverdraw();
void DBG_ShowIntensity();
void DBG_ShowDepthBuffer();
void DBG_ShowLightCount();
void DBG_EnterWeaponDepthHack();
void DBG_EnterModelDepthHack( float depth );
void DBG_LeaveDepthHack();
void DBG_RenderDrawSurfListWithFunction( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowSilhouette();
void DBG_ShowTris( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowSurfaceInfo( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowViewEntitys( viewEntity_t* vModels );
void DBG_ShowTexturePolarity( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowUnsmoothedTangents( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowTangentSpace( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowVertexColor( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowNormals( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowTextureVectors( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowDominantTris( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowEdges( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_ShowLights();
void DBG_ShowPortals();
void DBG_ShowDebugText();
void DBG_ShowDebugLines();
void DBG_ShowDebugPolygons();
void DBG_ShowCenterOfProjection();
void DBG_TestGamma();
void DBG_TestGammaBias();
void DBG_TestImage();
void DBG_ShowTrace( drawSurf_t** drawSurfs, int numDrawSurfs );
void DBG_RenderDebugTools( drawSurf_t** drawSurfs, int numDrawSurfs );
public:
backEndCounters_t pc;
// surfaces used for code-based drawing
drawSurf_t unitSquareSurface;
drawSurf_t zeroOneCubeSurface;
drawSurf_t testImageSurface;
private:
uint64 glStateBits;
const viewDef_t* viewDef;
const viewEntity_t* currentSpace; // for detecting when a matrix must change
idScreenRect currentScissor; // for scissor clipping, local inside renderView viewport
bool currentRenderCopied; // true if any material has already referenced _currentRender
idRenderMatrix prevMVP[2]; // world MVP from previous frame for motion blur
// RB begin
idRenderMatrix shadowV[6]; // shadow depth view matrix
idRenderMatrix shadowP[6]; // shadow depth projection matrix
float hdrAverageLuminance;
float hdrMaxLuminance;
float hdrTime;
float hdrKey;
// RB end
private:
#if !defined( USE_VULKAN )
int currenttmu;
unsigned int currentVertexBuffer;
unsigned int currentIndexBuffer;
Framebuffer* currentFramebuffer; // RB: for offscreen rendering
int faceCulling;
vertexLayoutType_t vertexLayout;
float polyOfsScale;
float polyOfsBias;
#if 0
unsigned short gammaTable[ 256 ]; // brightness / gamma modify this
idStr rendererString;
idStr vendorString;
idStr versionString;
idStr extensionsString;
idStr wglExtensionsString;
idStr shadingLanguageString;
float glVersion; // atof( version_string )
graphicsVendor_t vendor;
int maxTextureSize; // queried from GL
int maxTextureCoords;
int maxTextureImageUnits;
int uniformBufferOffsetAlignment;
int colorBits;
int depthBits;
int stencilBits;
bool depthBoundsTestAvailable;
bool timerQueryAvailable;
bool swapControlTearAvailable;
int displayFrequency;
#endif
#endif // !defined( USE_VULKAN )
};
#endif

View file

@ -675,15 +675,6 @@ struct performanceCounters_t
};
struct tmu_t
{
unsigned int current2DMap;
unsigned int current2DArray;
unsigned int currentCubeMap;
};
const int MAX_MULTITEXTURE_UNITS = 8;
enum vertexLayoutType_t
{
@ -693,78 +684,30 @@ enum vertexLayoutType_t
LAYOUT_DRAW_SHADOW_VERT_SKINNED
};
/*
struct glstate_t
{
tmu_t tmu[MAX_MULTITEXTURE_UNITS];
int currenttmu;
int faceCulling;
vertexLayoutType_t vertexLayout;
// RB: 64 bit fixes, changed unsigned int to uintptr_t
uintptr_t currentVertexBuffer;
uintptr_t currentIndexBuffer;
Framebuffer* currentFramebuffer;
// RB end
float polyOfsScale;
float polyOfsBias;
uint64 glStateBits;
};
struct backEndCounters_t
{
int c_surfaces;
int c_shaders;
int c_drawElements;
int c_drawIndexes;
int c_shadowElements;
int c_shadowIndexes;
int c_copyFrameBuffer;
float c_overDraw;
int totalMicroSec; // total microseconds for backend run
int shadowMicroSec;
};
// all state modified by the back end is separated
// from the front end state
struct backEndState_t
{
const viewDef_t* viewDef;
backEndCounters_t pc;
const viewEntity_t* currentSpace; // for detecting when a matrix must change
idScreenRect currentScissor; // for scissor clipping, local inside renderView viewport
glstate_t glState; // for OpenGL state deltas
bool currentRenderCopied; // true if any material has already referenced _currentRender
idRenderMatrix prevMVP[2]; // world MVP from previous frame for motion blur, per-eye
// RB begin
idRenderMatrix shadowV[6]; // shadow depth view matrix
idRenderMatrix shadowP[6]; // shadow depth projection matrix
float hdrAverageLuminance;
float hdrMaxLuminance;
float hdrTime;
float hdrKey;
// RB end
// surfaces used for code-based drawing
drawSurf_t unitSquareSurface;
drawSurf_t zeroOneCubeSurface;
drawSurf_t testImageSurface;
};
*/
class idParallelJobList;
@ -773,6 +716,8 @@ const int MAX_GUI_SURFACES = 1024; // default size of the drawSurfs list for gu
static const int MAX_RENDER_CROPS = 8;
#include "RenderBackend.h"
/*
** Most renderer globals are defined here.
** backend functions should never modify any of these fields,
@ -844,6 +789,7 @@ public:
virtual void UnCrop();
virtual bool UploadImage( const char* imageName, const byte* data, int width, int height );
void PrintPerformanceCounters();
public:
@ -927,10 +873,11 @@ public:
idParallelJobList* frontEndJobList;
idRenderBackend backend;
unsigned timerQueryId; // for GL_TIME_ELAPSED_EXT queries
};
extern backEndState_t backEnd;
extern idRenderSystemLocal tr;
extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared during ref re-init
@ -1471,15 +1418,7 @@ struct localTrace_t
localTrace_t R_LocalTrace( const idVec3& start, const idVec3& end, const float radius, const srfTriangles_t* tri );
void RB_ShowTrace( drawSurf_t** drawSurfs, int numDrawSurfs );
/*
=============================================================
BACKEND
=============================================================
*/
void RB_ExecuteBackEndCommands( const emptyCommand_t* cmds );
/*
============================================================
@ -1490,7 +1429,6 @@ TR_BACKEND_DRAW
*/
void RB_SetMVP( const idRenderMatrix& mvp );
void RB_DrawElementsWithCounters( const drawSurf_t* surf );
void RB_DrawViewInternal( const viewDef_t* viewDef, const int stereoEye );
void RB_DrawView( const void* data, const int stereoEye );
void RB_CopyRender( const void* data );

View file

@ -44,56 +44,56 @@ This prints both front and back end counters, so it should
only be called when the back end thread is idle.
=====================
*/
static void R_PerformanceCounters()
void idRenderSystemLocal::PrintPerformanceCounters()
{
if( r_showPrimitives.GetInteger() != 0 )
{
common->Printf( "views:%i draws:%i tris:%i (shdw:%i)\n",
tr.pc.c_numViews,
backEnd.pc.c_drawElements + backEnd.pc.c_shadowElements,
( backEnd.pc.c_drawIndexes + backEnd.pc.c_shadowIndexes ) / 3,
backEnd.pc.c_shadowIndexes / 3
pc.c_numViews,
backend.pc.c_drawElements + backend.pc.c_shadowElements,
( backend.pc.c_drawIndexes + backend.pc.c_shadowIndexes ) / 3,
backend.pc.c_shadowIndexes / 3
);
}
if( r_showDynamic.GetBool() )
{
common->Printf( "callback:%i md5:%i dfrmVerts:%i dfrmTris:%i tangTris:%i guis:%i\n",
tr.pc.c_entityDefCallbacks,
tr.pc.c_generateMd5,
tr.pc.c_deformedVerts,
tr.pc.c_deformedIndexes / 3,
tr.pc.c_tangentIndexes / 3,
tr.pc.c_guiSurfs
pc.c_entityDefCallbacks,
pc.c_generateMd5,
pc.c_deformedVerts,
pc.c_deformedIndexes / 3,
pc.c_tangentIndexes / 3,
pc.c_guiSurfs
);
}
if( r_showCull.GetBool() )
{
common->Printf( "%i box in %i box out\n",
tr.pc.c_box_cull_in, tr.pc.c_box_cull_out );
pc.c_box_cull_in, pc.c_box_cull_out );
}
if( r_showAddModel.GetBool() )
{
common->Printf( "callback:%i createInteractions:%i createShadowVolumes:%i\n",
tr.pc.c_entityDefCallbacks, tr.pc.c_createInteractions, tr.pc.c_createShadowVolumes );
common->Printf( "viewEntities:%i shadowEntities:%i viewLights:%i\n", tr.pc.c_visibleViewEntities,
tr.pc.c_shadowViewEntities, tr.pc.c_viewLights );
pc.c_entityDefCallbacks, pc.c_createInteractions, pc.c_createShadowVolumes );
common->Printf( "viewEntities:%i shadowEntities:%i viewLights:%i\n", pc.c_visibleViewEntities,
pc.c_shadowViewEntities, pc.c_viewLights );
}
if( r_showUpdates.GetBool() )
{
common->Printf( "entityUpdates:%i entityRefs:%i lightUpdates:%i lightRefs:%i\n",
tr.pc.c_entityUpdates, tr.pc.c_entityReferences,
tr.pc.c_lightUpdates, tr.pc.c_lightReferences );
pc.c_entityUpdates, pc.c_entityReferences,
pc.c_lightUpdates, pc.c_lightReferences );
}
if( r_showMemory.GetBool() )
{
common->Printf( "frameData: %i (%i)\n", frameData->frameMemoryAllocated.GetValue(), frameData->highWaterAllocated );
}
memset( &tr.pc, 0, sizeof( tr.pc ) );
memset( &backEnd.pc, 0, sizeof( backEnd.pc ) );
memset( &pc, 0, sizeof( pc ) );
memset( &backend.pc, 0, sizeof( backend.pc ) );
}
/*
@ -136,14 +136,14 @@ void idRenderSystemLocal::RenderCommandBuffers( const emptyCommand_t* const cmdH
glGenQueries( 1, & tr.timerQueryId );
}
glBeginQuery( GL_TIME_ELAPSED_EXT, tr.timerQueryId );
RB_ExecuteBackEndCommands( cmdHead );
ExecuteBackEndCommands( cmdHead );
glEndQuery( GL_TIME_ELAPSED_EXT );
glFlush();
}
else
#endif
{
RB_ExecuteBackEndCommands( cmdHead );
ExecuteBackEndCommands( cmdHead );
}
}
@ -784,15 +784,15 @@ void idRenderSystemLocal::SwapCommandBuffers_FinishRendering(
}
if( backEndMicroSec != NULL )
{
*backEndMicroSec = backEnd.pc.totalMicroSec;
*backEndMicroSec = backend.pc.totalMicroSec;
}
if( shadowMicroSec != NULL )
{
*shadowMicroSec = backEnd.pc.shadowMicroSec;
*shadowMicroSec = backend.pc.shadowMicroSec;
}
// print any other statistics and clear all of them
R_PerformanceCounters();
PrintPerformanceCounters();
// check for dynamic changes that require some initialization
R_CheckCvars();
@ -829,9 +829,9 @@ const emptyCommand_t* idRenderSystemLocal::SwapCommandBuffers_FinishCommandBuffe
// copy the code-used drawsurfs that were
// allocated at the start of the buffer memory to the backEnd referenced locations
backEnd.unitSquareSurface = tr.unitSquareSurface_;
backEnd.zeroOneCubeSurface = tr.zeroOneCubeSurface_;
backEnd.testImageSurface = tr.testImageSurface_;
backend.unitSquareSurface = tr.unitSquareSurface_;
backend.zeroOneCubeSurface = tr.zeroOneCubeSurface_;
backend.testImageSurface = tr.testImageSurface_;
// use the other buffers next frame, because another CPU
// may still be rendering into the current buffers