mirror of
https://github.com/intel/intel-graphics-compiler.git
synced 2025-11-04 08:21:06 +08:00
608 lines
16 KiB
C++
608 lines
16 KiB
C++
/*========================== begin_copyright_notice ============================
|
|
|
|
Copyright (C) 2017-2021 Intel Corporation
|
|
|
|
SPDX-License-Identifier: MIT
|
|
|
|
============================= end_copyright_notice ===========================*/
|
|
|
|
#pragma once
|
|
|
|
#include "Object.h"
|
|
|
|
#ifndef ASSERT
|
|
#include "..\..\d3d\ibdw\d3ddebug.h"
|
|
#endif
|
|
|
|
namespace iSTD
|
|
{
|
|
|
|
/*****************************************************************************\
|
|
Template Parameters
|
|
\*****************************************************************************/
|
|
#define FastMaskTemplateList bool OrderedList
|
|
#define CFastMaskSetType CFastMask<OrderedList>
|
|
|
|
/*****************************************************************************\
|
|
|
|
Class:
|
|
FastMask
|
|
|
|
Description:
|
|
Simple ordered mask with minimal set list traversal
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
class CFastMask
|
|
{
|
|
public:
|
|
CFastMask( unsigned int inSize );
|
|
virtual ~CFastMask();
|
|
|
|
inline bool IsValid( void ) const;
|
|
inline bool IsSet( unsigned int index ) const;
|
|
inline bool IsDirty ( void );
|
|
inline const unsigned int* GetMask(unsigned int &ioSetKey);
|
|
inline unsigned int GetSize();
|
|
inline unsigned int GetSetListSize();
|
|
inline void GetUnsortedSetList( unsigned int const** ioList, unsigned int &ioSize );
|
|
inline void GetSetList( unsigned int const** ioList, unsigned int &ioSize );
|
|
inline void SetBits( unsigned int index, unsigned int count );
|
|
inline void SetBit( unsigned int index );
|
|
inline void ClearBits( void );
|
|
inline void UnSetBit( unsigned int index );
|
|
inline void Resize ( unsigned int in_NewSize );
|
|
|
|
protected:
|
|
inline void SortSetList( void );
|
|
inline void CollapseSetList( void );
|
|
|
|
unsigned int* m_Mask;
|
|
unsigned int* m_SetList;
|
|
unsigned int m_Key;
|
|
unsigned int m_SortIdx;
|
|
unsigned int m_CollapseIdx;
|
|
unsigned int m_SetListSize;
|
|
unsigned int m_Capacity;
|
|
bool m_SortOnGet;
|
|
bool m_CollapseUnsorted;
|
|
};
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
Constructor
|
|
|
|
Description:
|
|
Constructs a mask with the incoming size
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
CFastMaskSetType::CFastMask( unsigned int inSize )
|
|
: m_Mask(0)
|
|
, m_SetList(0)
|
|
, m_Key(1)
|
|
, m_SortIdx(0)
|
|
, m_CollapseIdx(0)
|
|
, m_SetListSize(0)
|
|
, m_Capacity(inSize)
|
|
, m_SortOnGet(false)
|
|
, m_CollapseUnsorted(false)
|
|
{
|
|
ASSERT(inSize > 0);
|
|
|
|
if( inSize > 0 )
|
|
{
|
|
m_Mask = new unsigned int[m_Capacity];
|
|
m_SetList = new unsigned int[m_Capacity];
|
|
|
|
ASSERT(0 != m_Mask);
|
|
ASSERT(0 != m_SetList);
|
|
|
|
if( m_Mask && m_SetList )
|
|
{
|
|
// quick run up to next power of 2
|
|
while( (unsigned int)m_Key <= m_Capacity )
|
|
{
|
|
m_Key = m_Key << 1;
|
|
}
|
|
|
|
// clear mask
|
|
for( unsigned int i = 0; i < m_Capacity; i++ )
|
|
{
|
|
m_Mask[i] = m_Key;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SafeDeleteArray( m_Mask );
|
|
SafeDeleteArray( m_SetList );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
Destructor
|
|
|
|
Description:
|
|
Cleanup memory
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
CFastMaskSetType::~CFastMask( void )
|
|
{
|
|
SafeDeleteArray(m_Mask);
|
|
SafeDeleteArray(m_SetList);
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
IsValid
|
|
|
|
Description:
|
|
Returns whether the object has been constructed properly.
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
bool CFastMaskSetType::IsValid( void ) const
|
|
{
|
|
return ( ( m_Mask != NULL ) && ( m_SetList != NULL ) );
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
IsSet
|
|
|
|
Description:
|
|
Returns whether or not a bit has been set in the mask.
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
bool CFastMaskSetType::IsSet( unsigned int index ) const
|
|
{
|
|
ASSERT( index < m_Capacity );
|
|
return ( m_Key != m_Mask[index] );
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
IsDirty
|
|
|
|
Description:
|
|
Returns whether or not the mask is dirty
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
bool CFastMaskSetType::IsDirty( void )
|
|
{
|
|
if( true == m_CollapseUnsorted )
|
|
{
|
|
CollapseSetList();
|
|
}
|
|
|
|
return (m_SetListSize > 0);
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
GetMask
|
|
|
|
Description:
|
|
Get the current mask with the set key for use in optimal comparisons for
|
|
multiple bits.
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
const unsigned int* CFastMaskSetType::GetMask( unsigned int &ioSetKey )
|
|
{
|
|
ioSetKey = m_Key;
|
|
|
|
return m_Mask;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
GetSize
|
|
|
|
Description:
|
|
Returns the number of possible indices.
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
unsigned int CFastMaskSetType::GetSize( void )
|
|
{
|
|
return m_Capacity;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
GetSetListSize
|
|
|
|
Description:
|
|
Returns the number set indices
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
unsigned int CFastMaskSetType::GetSetListSize( void )
|
|
{
|
|
if( true == m_CollapseUnsorted )
|
|
{
|
|
CollapseSetList();
|
|
}
|
|
|
|
return m_SetListSize;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
SetBits
|
|
|
|
Description:
|
|
Sets mask bits from index to count.
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
void CFastMaskSetType::SetBits( unsigned int index, unsigned int count )
|
|
{
|
|
ASSERT( (index + count) <= m_Capacity );
|
|
for( unsigned int i = index; i < index + count; i++ )
|
|
{
|
|
if( m_Key == m_Mask[i] )
|
|
{
|
|
// when the user sets/un-sets bits often without a Get* then there
|
|
// exists a possibility of overrunning the setlist.
|
|
if( m_SetListSize >= m_Capacity )
|
|
{
|
|
CollapseSetList();
|
|
}
|
|
|
|
ASSERT(m_SetListSize < m_Capacity);
|
|
m_Mask[i] = m_SetListSize;
|
|
m_SetList[m_SetListSize++] = i;
|
|
|
|
if( OrderedList )
|
|
{
|
|
m_SortOnGet = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
SetBit
|
|
|
|
Description:
|
|
Sets mask bit for index
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
void CFastMaskSetType::SetBit( unsigned int index )
|
|
{
|
|
ASSERT( index < m_Capacity );
|
|
if( m_Key == m_Mask[index] )
|
|
{
|
|
if( m_SetListSize >= m_Capacity )
|
|
{
|
|
CollapseSetList();
|
|
}
|
|
|
|
ASSERT(m_SetListSize < m_Capacity);
|
|
m_Mask[index] = m_SetListSize;
|
|
m_SetList[m_SetListSize++] = index;
|
|
|
|
if( OrderedList )
|
|
{
|
|
m_SortOnGet = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
GetUnsortedSetList
|
|
|
|
Description:
|
|
Gets an unsorted set list as an override if the list is sorted but you don't
|
|
require sorting at this point.
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
void CFastMaskSetType::GetUnsortedSetList( unsigned int const** ioList, unsigned int &ioSize )
|
|
{
|
|
if( true == m_CollapseUnsorted )
|
|
{
|
|
CollapseSetList();
|
|
}
|
|
|
|
*ioList = m_SetList;
|
|
ioSize = m_SetListSize;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
GetSetList
|
|
|
|
Description:
|
|
Gets the set list for traversal
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
void CFastMaskSetType::GetSetList( unsigned int const** ioList, unsigned int &ioSize )
|
|
{
|
|
if( OrderedList && ( true == m_SortOnGet ) )
|
|
{
|
|
SortSetList();
|
|
}
|
|
else if( true == m_CollapseUnsorted )
|
|
{
|
|
CollapseSetList();
|
|
}
|
|
|
|
*ioList = m_SetList;
|
|
ioSize = m_SetListSize;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
ClearBits
|
|
|
|
Description:
|
|
Remove the bit from the list and mask if necessary
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
void CFastMaskSetType::ClearBits( void )
|
|
{
|
|
unsigned int index = 0;
|
|
|
|
// walk the set list and remove set elements
|
|
for( unsigned int i = 0; i < m_SetListSize; i++ )
|
|
{
|
|
index = m_SetList[i];
|
|
|
|
// the user can un-set bits prior to calling clear and we need to ensure
|
|
// that we dont try to change those entries as they dont matter and could
|
|
// corrupt the heap
|
|
if( index != m_Key )
|
|
{
|
|
m_Mask[index] = m_Key;
|
|
}
|
|
}
|
|
|
|
m_SetListSize = 0;
|
|
m_SortIdx = 0;
|
|
m_CollapseIdx = 0;
|
|
m_SortOnGet = false;
|
|
m_CollapseUnsorted = false;
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
UnSetBit
|
|
|
|
Description:
|
|
Remove the bit from the list and mask if necessary
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
void CFastMaskSetType::UnSetBit( unsigned int index )
|
|
{
|
|
ASSERT( index < m_Capacity );
|
|
|
|
// we do not change the setlist size because we will rely
|
|
// upon the sort to remove those key elements
|
|
if( m_Key != m_Mask[index] )
|
|
{
|
|
// set that we need to collapse this list, required if we query an
|
|
// unsorted set from a sorted set list
|
|
m_CollapseUnsorted = true;
|
|
|
|
unsigned int setListPos = m_Mask[index];
|
|
if( setListPos < m_CollapseIdx )
|
|
{
|
|
m_CollapseIdx = setListPos; // we need to start our collapse at this index
|
|
}
|
|
|
|
// handle ordered list
|
|
if( OrderedList )
|
|
{
|
|
// if we are an ordered list we need to compare the index position
|
|
// with the current sort index and modify that index if necessary
|
|
if( setListPos < m_SortIdx )
|
|
{
|
|
m_SortIdx = setListPos; // move index down to allow for collapse
|
|
}
|
|
|
|
m_SortOnGet = true;
|
|
}
|
|
|
|
m_SetList[m_Mask[index]] = m_Key;
|
|
m_Mask[index] = m_Key;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
Resize
|
|
|
|
Description:
|
|
Resizes the FastMask.
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
void CFastMaskSetType::Resize( unsigned int in_NewSize )
|
|
{
|
|
ASSERT(in_NewSize != 0);
|
|
|
|
if( in_NewSize == m_Capacity )
|
|
return;
|
|
|
|
unsigned int* old_m_SetList = m_SetList;
|
|
unsigned int old_m_SetListSize = m_SetListSize;
|
|
|
|
m_SetListSize = 0; //will be using SetBits() which will correct this value
|
|
m_CollapseIdx = 0;
|
|
m_SortIdx = 0;
|
|
m_Capacity = in_NewSize;
|
|
m_CollapseUnsorted = false;
|
|
m_SortOnGet = false;
|
|
|
|
SafeDeleteArray(m_Mask);
|
|
m_Mask = new unsigned int[m_Capacity];
|
|
m_SetList = new unsigned int[m_Capacity];
|
|
|
|
ASSERT(0 != m_Mask);
|
|
ASSERT(0 != m_SetList);
|
|
|
|
// save off old key
|
|
unsigned int old_m_Key = m_Key;
|
|
m_Key = 1;
|
|
|
|
// quick run up to next power of 2
|
|
while( (unsigned int)m_Key <= m_Capacity )
|
|
{
|
|
m_Key = m_Key << 1;
|
|
}
|
|
|
|
for( unsigned int i = 0; i < m_Capacity; i++)
|
|
{
|
|
m_Mask[i] = m_Key;
|
|
}
|
|
|
|
for( unsigned int i = 0; i < old_m_SetListSize; i++)
|
|
{
|
|
if(old_m_SetList[i] != old_m_Key)
|
|
{
|
|
SetBit(old_m_SetList[i]);
|
|
}
|
|
}
|
|
|
|
SafeDeleteArray(old_m_SetList);
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
SortSetList
|
|
|
|
Description:
|
|
Sorts the set list, a modified insertion sort algorithm
|
|
http://en.wikipedia.org/wiki/Insertion_sort
|
|
|
|
\*****************************************************************************/
|
|
template<FastMaskTemplateList>
|
|
void CFastMaskSetType::SortSetList( )
|
|
{
|
|
// perform an insertion sort in place
|
|
unsigned int count = 0;
|
|
unsigned int keyVal = 0;
|
|
int idx;
|
|
|
|
for( unsigned int i = m_SortIdx; i < m_SetListSize; i++ )
|
|
{
|
|
keyVal = m_SetList[i];
|
|
|
|
// handle un-set bit
|
|
if( keyVal == m_Key )
|
|
{
|
|
count++; // increment number of un-set keys seen, these will
|
|
// automatically be sorted to the RHS of the list
|
|
}
|
|
|
|
idx = i - 1;
|
|
|
|
// find the sort position for this keyVal
|
|
while( idx >= 0 && m_SetList[idx] > keyVal )
|
|
{
|
|
m_SetList[idx+1] = m_SetList[idx];
|
|
idx--;
|
|
}
|
|
|
|
m_SetList[idx+1] = keyVal;
|
|
}
|
|
|
|
m_SetListSize -= count; // subtract off the number of un-set bits on the RHS
|
|
m_SortOnGet = false;
|
|
m_CollapseUnsorted = false;
|
|
m_SortIdx = ( m_SetListSize > 0 ) ? m_SetListSize - 1 : 0;
|
|
m_CollapseIdx = m_SortIdx;
|
|
|
|
// update the mask with the new positions
|
|
for( unsigned int i = 0; i < m_SetListSize; i++ )
|
|
{
|
|
m_Mask[m_SetList[i]] = i; // new index
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************\
|
|
|
|
Function:
|
|
CollapseSetList
|
|
|
|
Description:
|
|
Removes any un-set bits from the set list
|
|
|
|
\*****************************************************************************/
|
|
|
|
template<FastMaskTemplateList>
|
|
void CFastMaskSetType::CollapseSetList( )
|
|
{
|
|
// walk the set list and collapse by skipping over un-set elements
|
|
unsigned int count = m_CollapseIdx;
|
|
|
|
for( unsigned int i = m_CollapseIdx; i < m_SetListSize; i++ )
|
|
{
|
|
if( m_Key != m_SetList[i] )
|
|
{
|
|
m_Mask[m_SetList[i]] = count; // update mask with new position
|
|
m_SetList[count++] = m_SetList[i];
|
|
}
|
|
}
|
|
|
|
m_CollapseUnsorted = false;
|
|
m_SetListSize = count;
|
|
|
|
if( 0 == m_SetListSize )
|
|
{
|
|
m_SortIdx = 0;
|
|
m_CollapseIdx = 0;
|
|
|
|
if( OrderedList )
|
|
{
|
|
m_SortOnGet = false; // no need to sort if empty
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( m_CollapseIdx < m_SortIdx )
|
|
{
|
|
m_SortIdx = m_CollapseIdx;
|
|
|
|
if( OrderedList )
|
|
{
|
|
m_SortOnGet = true;
|
|
}
|
|
}
|
|
|
|
m_CollapseIdx = m_SetListSize - 1;
|
|
}
|
|
}
|
|
|
|
} // iSTD
|