/* ============== idVertexCache::BeginBackEnd ============== */ void idVertexCache::BeginBackEnd() { mostUsedVertex = Max( mostUsedVertex, frameData[listNum].vertexMemUsed.GetValue() ); mostUsedIndex = Max( mostUsedIndex, frameData[listNum].indexMemUsed.GetValue() ); mostUsedJoint = Max( mostUsedJoint, frameData[listNum].jointMemUsed.GetValue() ); if ( r_showVertexCache.GetBool() ) { idLib::Printf( "%08d: %d allocations, %dkB vertex, %dkB index, %kB joint : %dkB vertex, %dkB index, %kB joint\n", currentFrame, frameData[listNum].allocations, frameData[listNum].vertexMemUsed.GetValue() / 1024, frameData[listNum].indexMemUsed.GetValue() / 1024, frameData[listNum].jointMemUsed.GetValue() / 1024, mostUsedVertex / 1024, mostUsedIndex / 1024, mostUsedJoint / 1024 ); } EndBackEnd(); drawListNum = listNum; // prepare the next frame for writing to by the CPU currentFrame++; listNum = currentFrame % VERTCACHE_NUM_FRAMES; const int startMap = Sys_Milliseconds(); MapGeoBufferSet( frameData[listNum] ); const int endMap = Sys_Milliseconds(); if ( endMap - startMap > 1 ) { idLib::PrintfIf( r_showVertexCacheTimings.GetBool(), "idVertexCache::map took %i msec\n", endMap - startMap ); } ClearGeoBufferSet( frameData[listNum] ); }
/* ============== idVertexCache::BeginBackEnd ============== */ void idVertexCache::BeginBackEnd() { mostUsedVertex = Max( mostUsedVertex, frameData[listNum].vertexMemUsed.GetValue() ); mostUsedIndex = Max( mostUsedIndex, frameData[listNum].indexMemUsed.GetValue() ); mostUsedJoint = Max( mostUsedJoint, frameData[listNum].jointMemUsed.GetValue() ); if( r_showVertexCache.GetBool() ) { idLib::Printf( "%08d: %d allocations, %dkB vertex, %dkB index, %ikB joint : %dkB vertex, %dkB index, %ikB joint\n", currentFrame, frameData[listNum].allocations, frameData[listNum].vertexMemUsed.GetValue() / 1024, frameData[listNum].indexMemUsed.GetValue() / 1024, frameData[listNum].jointMemUsed.GetValue() / 1024, mostUsedVertex / 1024, mostUsedIndex / 1024, mostUsedJoint / 1024 ); } // unmap the current frame so the GPU can read it const int startUnmap = Sys_Milliseconds(); UnmapGeoBufferSet( frameData[listNum] ); UnmapGeoBufferSet( staticData ); const int endUnmap = Sys_Milliseconds(); if( endUnmap - startUnmap > 1 ) { idLib::PrintfIf( r_showVertexCacheTimings.GetBool(), "idVertexCache::unmap took %i msec\n", endUnmap - startUnmap ); } drawListNum = listNum; // prepare the next frame for writing to by the CPU currentFrame++; listNum = currentFrame % VERTCACHE_NUM_FRAMES; const int startMap = Sys_Milliseconds(); MapGeoBufferSet( frameData[listNum] ); const int endMap = Sys_Milliseconds(); if( endMap - startMap > 1 ) { idLib::PrintfIf( r_showVertexCacheTimings.GetBool(), "idVertexCache::map took %i msec\n", endMap - startMap ); } ClearGeoBufferSet( frameData[listNum] ); #if 0 const int startBind = Sys_Milliseconds(); glBindBuffer( GL_ARRAY_BUFFER, ( GLuint )frameData[drawListNum].vertexBuffer.GetAPIObject() ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ( GLuint )frameData[drawListNum].indexBuffer.GetAPIObject() ); const int endBind = Sys_Milliseconds(); if( endBind - startBind > 1 ) { idLib::Printf( "idVertexCache::bind took %i msec\n", endBind - startBind ); } #endif }
/* ============== idVertexCache::ActuallyAlloc ============== */ vertCacheHandle_t idVertexCache::ActuallyAlloc( geoBufferSet_t & vcs, const void * data, int bytes, cacheType_t type ) { if ( bytes == 0 ) { return (vertCacheHandle_t)0; } assert( ( ((UINT_PTR)(data)) & 15 ) == 0 ); assert( ( bytes & 15 ) == 0 ); // thread safe interlocked adds byte ** base = NULL; int endPos = 0; if ( type == CACHE_INDEX ) { base = &vcs.mappedIndexBase; endPos = vcs.indexMemUsed.Add( bytes ); if ( endPos > vcs.indexBuffer.GetAllocedSize() ) { idLib::Error( "Out of index cache" ); } } else if ( type == CACHE_VERTEX ) { base = &vcs.mappedVertexBase; endPos = vcs.vertexMemUsed.Add( bytes ); if ( endPos > vcs.vertexBuffer.GetAllocedSize() ) { idLib::Error( "Out of vertex cache" ); } } else if ( type == CACHE_JOINT ) { base = &vcs.mappedJointBase; endPos = vcs.jointMemUsed.Add( bytes ); if ( endPos > vcs.jointBuffer.GetAllocedSize() ) { idLib::Error( "Out of joint buffer cache" ); } } else { assert( false ); } vcs.allocations++; int offset = endPos - bytes; // Actually perform the data transfer if ( data != NULL ) { MapGeoBufferSet( vcs ); CopyBuffer( *base + offset, (const byte *)data, bytes ); } vertCacheHandle_t handle = ( (uint64)(currentFrame & VERTCACHE_FRAME_MASK ) << VERTCACHE_FRAME_SHIFT ) | ( (uint64)(offset & VERTCACHE_OFFSET_MASK ) << VERTCACHE_OFFSET_SHIFT ) | ( (uint64)(bytes & VERTCACHE_SIZE_MASK ) << VERTCACHE_SIZE_SHIFT ); if ( &vcs == &staticData ) { handle |= VERTCACHE_STATIC; } return handle; }
/* ============== idVertexCache::Init ============== */ void idVertexCache::Init( bool restart ) { currentFrame = 0; listNum = 0; mostUsedVertex = 0; mostUsedIndex = 0; mostUsedJoint = 0; for ( int i = 0; i < VERTCACHE_NUM_FRAMES; i++ ) { AllocGeoBufferSet( frameData[i], VERTCACHE_VERTEX_MEMORY_PER_FRAME, VERTCACHE_INDEX_MEMORY_PER_FRAME, VERTCACHE_JOINT_MEMORY_PER_FRAME ); } AllocGeoBufferSet( staticData, STATIC_VERTEX_MEMORY, STATIC_INDEX_MEMORY, 0 ); MapGeoBufferSet( frameData[listNum] ); }