Esempio n. 1
0
// Calls glUseProgram() as a side effect
CGLMShaderPair	*CGLMShaderPairCache::SelectShaderPairInternal( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits, int rowIndex )
{
	CGLMShaderPair	*result = NULL;
		
#if GLMDEBUG
	int loglevel = gl_shaderpair_cachelog.GetInt();
#else
	const int loglevel = 0;
#endif

	char vtempname[128];
	int vtempindex = -1; vtempindex;
	int vtempcombo = -1; vtempcombo;

	char ptempname[128];
	int ptempindex = -1; ptempindex;
	int ptempcombo = -1; ptempcombo;
	
	CGLMPairCacheEntry *row = HashRowPtr( rowIndex );
	
	// Re-probe to find the oldest and first unoccupied entry (this func should be very rarely called if the cache is properly configured so re-scanning shouldn't matter).
	int hitway, emptyway, oldestway;
	HashRowProbe( row, vp, fp, extraKeyBits, hitway, emptyway, oldestway );
	Assert( hitway == -1 );

	// we missed.  if there is no empty way, then somebody's getting evicted.
	int destway = -1;
		
	if (emptyway>=0)
	{			
		destway = emptyway;

		if (loglevel >= 2)  // misses logged at level 3 and higher
		{
			printf("\nSSP: miss - row %05d - ", rowIndex );
		}
	}
	else
	{
		// evict the oldest way
		Assert( oldestway >= 0);	// better not come back negative
			
		CGLMPairCacheEntry *evict = row + oldestway;
			
		Assert( evict->m_pair != NULL );
		Assert( evict->m_pair != m_ctx->m_pBoundPair );	// just check
			
		///////////////////////FIXME may need to do a shoot-down if the pair being evicted is currently active in the context
			
		m_evictions[ rowIndex ]++;

		// log eviction if desired
		if (loglevel >= 2)  // misses logged at level 3 and higher
		{
			//evict->m_vertexProg->GetLabelIndexCombo( vtempname, sizeof(vtempname), &vtempindex, &vtempcombo );
			//evict->m_fragmentProg->GetLabelIndexCombo( ptempname, sizeof(ptempname), &ptempindex, &ptempcombo );
			//printf("\nSSP: miss - row %05d - [ %s/%d/%d %s/%d/%d ]'s %d'th eviction - ", rowIndex, vtempname, vtempindex, vtempcombo, ptempname, ptempindex, ptempcombo, m_evictions[ rowIndex ] );

			evict->m_vertexProg->GetComboIndexNameString( vtempname, sizeof(vtempname) );
			evict->m_fragmentProg->GetComboIndexNameString( ptempname, sizeof(ptempname) );				
			printf("\nSSP: miss - row %05d - [ %s + %s ]'s %d'th eviction - ", rowIndex, vtempname, ptempname, m_evictions[ rowIndex ] );
		}

		delete evict->m_pair;	evict->m_pair = NULL;
		memset( evict, 0, sizeof(*evict) );
			
		destway = oldestway;
	}

	// make the new entry
	CGLMPairCacheEntry *newentry = row + destway;
		
	newentry->m_lastMark = m_mark;
	newentry->m_vertexProg = vp;
	newentry->m_fragmentProg = fp;
	newentry->m_extraKeyBits = extraKeyBits;
	newentry->m_pair = new CGLMShaderPair( m_ctx );
	Assert( newentry->m_pair );
	newentry->m_pair->SetProgramPair( vp, fp );

	if (loglevel >= 2)  // say a little bit more
	{
		//newentry->m_vertexProg->GetLabelIndexCombo( vtempname, sizeof(vtempname), &vtempindex, &vtempcombo );
		//newentry->m_fragmentProg->GetLabelIndexCombo( ptempname, sizeof(ptempname), &ptempindex, &ptempcombo );			
		//printf("new [ %s/%d/%d %s/%d/%d ]", vtempname, vtempindex, vtempcombo, ptempname, ptempindex, ptempcombo );

		newentry->m_vertexProg->GetComboIndexNameString( vtempname, sizeof(vtempname) );
		newentry->m_fragmentProg->GetComboIndexNameString( ptempname, sizeof(ptempname) );				
		printf("new [ %s + %s ]", vtempname, ptempname );
	}

	m_mark = m_mark+1;
	if (!m_mark)		// somewhat unlikely this will ever be reached.. but we need to avoid zero as a mark value
	{
		m_mark = 1;
	}

	result = newentry->m_pair;

	if (glm_cacheprograms.GetInt())
	{
		WriteToProgramCache( newentry->m_pair );
	}
		
	return result;
}
Esempio n. 2
0
CGLMShaderPair	*CGLMShaderPairCache::SelectShaderPair( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits )
{
	CGLMShaderPair	*result = NULL;

	int loglevel = gl_shaderpair_cachelog/* .GetInt() */;
	char vtempname[128];
	int vtempindex = -1;
	int vtempcombo = -1;

	char ptempname[128];
	int ptempindex = -1;
	int ptempcombo = -1;
		
	
	// select row where pair would be found if it exists
	uint rowIndex = HashRowIndex( vp, fp, extraKeyBits );
	
	CGLMPairCacheEntry *row = HashRowPtr( rowIndex );
	
	// probe row and see if we get a hit
	int hitway = -1;int emptyway = -1; int oldestway = -1;

	HashRowProbe( row, vp, fp, extraKeyBits, &hitway, &emptyway, &oldestway );
	
	if (hitway >=0)
	{
		// found it.  mark it and return
		CGLMPairCacheEntry *hit = row + hitway;
		hit->m_lastMark = m_mark;
		
		m_mark = m_mark+1;
		if (!m_mark)		// somewhat unlikely this will ever be reached.. but we need to avoid zero as a mark value
		{
			m_mark = 1;
		}
		
		// count the hit
		m_hits[ rowIndex ] ++;

		if (loglevel >= 3)  // hits logged at level 3 and higher
		{
			printf("\nSSP: hit  - row %05d - pair $%p (%d'th hit on row)",rowIndex, hit->m_pair, m_hits[ rowIndex ] );
		}

		result = hit->m_pair;
	}
	else
	{
		// we missed.  if there is no empty way, then somebody's getting evicted.
		int destway = -1;
		
		if (emptyway>=0)
		{			
			destway = emptyway;

			if (loglevel >= 2)  // misses logged at level 3 and higher
			{
				printf("\nSSP: miss - row %05d - ", rowIndex );
			}
		}
		else
		{
			// evict the oldest way
			Assert( oldestway >= 0);	// better not come back negative
			
			CGLMPairCacheEntry *evict = row + oldestway;
			
			Assert( evict->m_pair != NULL );
			Assert( evict->m_pair != m_ctx->m_boundPair );	// just check
			
			///////////////////////FIXME may need to do a shoot-down if the pair being evicted is currently active in the context
			
			m_evictions[ rowIndex ]++;

			// log eviction if desired
			if (loglevel >= 2)  // misses logged at level 3 and higher
			{
				//evict->m_vertexProg->GetLabelIndexCombo( vtempname, sizeof(vtempname), &vtempindex, &vtempcombo );
				//evict->m_fragmentProg->GetLabelIndexCombo( ptempname, sizeof(ptempname), &ptempindex, &ptempcombo );
				//printf("\nSSP: miss - row %05d - [ %s/%d/%d %s/%d/%d ]'s %d'th eviction - ", rowIndex, vtempname, vtempindex, vtempcombo, ptempname, ptempindex, ptempcombo, m_evictions[ rowIndex ] );

				evict->m_vertexProg->GetComboIndexNameString( vtempname, sizeof(vtempname) );
				evict->m_fragmentProg->GetComboIndexNameString( ptempname, sizeof(ptempname) );				
				printf("\nSSP: miss - row %05d - [ %s + %s ]'s %d'th eviction - ", rowIndex, vtempname, ptempname, m_evictions[ rowIndex ] );
			}

			delete evict->m_pair;	evict->m_pair = NULL;
			memset( evict, 0, sizeof(*evict) );
			
			destway = oldestway;
		}

		// make the new entry
		CGLMPairCacheEntry *newentry = row + destway;
		
		newentry->m_lastMark = m_mark;
		newentry->m_vertexProg = vp;
		newentry->m_fragmentProg = fp;
		newentry->m_extraKeyBits = extraKeyBits;
		newentry->m_pair = new CGLMShaderPair( m_ctx );
		newentry->m_pair->SetProgramPair( vp, fp );

		if (loglevel >= 2)  // say a little bit more
		{
			//newentry->m_vertexProg->GetLabelIndexCombo( vtempname, sizeof(vtempname), &vtempindex, &vtempcombo );
			//newentry->m_fragmentProg->GetLabelIndexCombo( ptempname, sizeof(ptempname), &ptempindex, &ptempcombo );			
			//printf("new [ %s/%d/%d %s/%d/%d ]", vtempname, vtempindex, vtempcombo, ptempname, ptempindex, ptempcombo );

			newentry->m_vertexProg->GetComboIndexNameString( vtempname, sizeof(vtempname) );
			newentry->m_fragmentProg->GetComboIndexNameString( ptempname, sizeof(ptempname) );				
			printf("new [ %s + %s ]", vtempname, ptempname );
		}

		m_mark = m_mark+1;
		if (!m_mark)		// somewhat unlikely this will ever be reached.. but we need to avoid zero as a mark value
		{
			m_mark = 1;
		}

		result = newentry->m_pair;

		/*
		if (glm_cacheprograms.GetInt())
		{
			WriteToProgramCache( newentry->m_pair );
		}
		*/
	}
	
	return result;
}