20 inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_z_
const char *name )
22 #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) 23 resource->SetPrivateData( WKPDID_D3DDebugObjectName, static_cast<UINT>(strlen(name)), name );
25 UNREFERENCED_PARAMETER(resource);
26 UNREFERENCED_PARAMETER(name);
30 template<UINT TNameLength>
31 inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_z_
const char (&name)[TNameLength])
33 #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) 34 resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, name);
36 UNREFERENCED_PARAMETER(resource);
37 UNREFERENCED_PARAMETER(name);
44 #define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p) = nullptr; } } 45 #define SAFE_ADDREF(p) { if (p) { (p)->AddRef(); } } 47 #define SAFE_DELETE_ARRAY(p) { delete [](p); p = nullptr; } 48 #define SAFE_DELETE(p) { delete (p); p = nullptr; } 51 #define __BREAK_ON_FAIL { __debugbreak(); } 53 #define __BREAK_ON_FAIL 56 #define VA(x, action) { hr = (x); if (FAILED(hr)) { action; __BREAK_ON_FAIL; return hr; } } 57 #define VNA(x,action) { if (!(x)) { action; __BREAK_ON_FAIL; hr = E_OUTOFMEMORY; goto lExit; } } 58 #define VBA(x,action) { if (!(x)) { action; __BREAK_ON_FAIL; hr = E_FAIL; goto lExit; } } 59 #define VHA(x,action) { hr = (x); if (FAILED(hr)) { action; __BREAK_ON_FAIL; goto lExit; } } 61 #define V(x) { VA (x, 0) } 62 #define VN(x) { VNA(x, 0) } 63 #define VB(x) { VBA(x, 0) } 64 #define VH(x) { VHA(x, 0) } 66 #define VBD(x,str) { VBA(x, DPF(1,str)) } 67 #define VHD(x,str) { VHA(x, DPF(1,str)) } 69 #define VEASSERT(x) { hr = (x); if (FAILED(hr)) { __BREAK_ON_FAIL; assert(!#x); goto lExit; } } 70 #define VNASSERT(x) { if (!(x)) { __BREAK_ON_FAIL; assert(!#x); hr = E_OUTOFMEMORY; goto lExit; } } 72 #define D3DX11FLTASSIGN(a,b) { *reinterpret_cast< UINT32* >(&(a)) = *reinterpret_cast< UINT32* >(&(b)); } 75 static const uint32_t c_DataAlignment =
sizeof(UINT_PTR);
77 inline uint32_t AlignToPowerOf2(uint32_t Value, uint32_t Alignment)
79 assert((Alignment & (Alignment - 1)) == 0);
81 _Analysis_assume_(Alignment > 0 && Value < MAXDWORD - Alignment);
82 return (Value + Alignment - 1) & (~(Alignment - 1));
85 inline void * AlignToPowerOf2(
void *pValue, UINT_PTR Alignment)
87 assert((Alignment & (Alignment - 1)) == 0);
89 return (
void *)(((UINT_PTR)pValue + Alignment - 1) & (~((UINT_PTR)Alignment - 1)));
105 HRESULT SetData(_In_reads_bytes_(size)
const void *pData, _In_
size_t size);
107 HRESULT Read(_Out_ uint32_t *pUint);
108 HRESULT Read(_Outptr_result_buffer_(size)
void **ppData, _In_
size_t size);
109 HRESULT Read(_Outptr_ LPCSTR *ppString);
111 HRESULT ReadAtOffset(_In_
size_t offset, _In_
size_t size, _Outptr_result_buffer_(size)
void **ppData);
112 HRESULT ReadAtOffset(_In_
size_t offset, _Outptr_result_z_ LPCSTR *ppString);
114 size_t GetPosition();
115 HRESULT Seek(_In_
size_t offset);
123 #if defined(_DEBUG) && !defined(_M_X64) && !defined(_M_ARM64) 132 _declspec(selectany)
unsigned int g_TimerRolloverCount = 0x80000000;
135 #endif // _DEBUG && !_M_X64 155 return Reserve(m_CurSize + 1);
158 HRESULT Reserve(_In_ uint32_t DesiredSize)
160 if (DesiredSize > m_MaxSize)
163 uint32_t newSize = std::max(m_MaxSize * 2, DesiredSize);
168 if ((newSize < m_MaxSize) || (newSize < m_CurSize) || (newSize >= UINT_MAX /
sizeof(T)))
170 m_hLastError = E_OUTOFMEMORY;
174 pNewData =
new uint8_t[newSize *
sizeof(T)];
175 if (pNewData ==
nullptr)
177 m_hLastError = E_OUTOFMEMORY;
183 memcpy(pNewData, m_pData, m_CurSize *
sizeof(T));
191 m_pCastData = (T*) m_pData;
197 HRESULT m_hLastError;
201 m_pCastData(
nullptr),
219 uint8_t tempData[
sizeof(*this)];
221 memcpy(tempData,
this,
sizeof(*
this));
222 memcpy(
this, &vOther,
sizeof(*
this));
223 memcpy(&vOther, tempData,
sizeof(*
this));
230 VN( m_pData =
new uint8_t[vOther.m_MaxSize *
sizeof(T)] );
232 m_CurSize = vOther.m_CurSize;
233 m_MaxSize = vOther.m_MaxSize;
234 m_hLastError = vOther.m_hLastError;
236 for (
size_t i = 0; i < m_CurSize; ++ i)
238 ((T*)m_pData)[i] = ((T*)vOther.m_pData)[i];
244 m_pCastData = (T*) m_pData;
253 SAFE_DELETE_ARRAY(m_pData);
256 m_pCastData =
nullptr;
260 void ClearWithoutDestructor()
264 SAFE_DELETE_ARRAY(m_pData);
268 m_pCastData =
nullptr;
276 for (
size_t i = 0; i < m_CurSize; ++ i)
278 ((T*)m_pData + i)->~T();
290 return new((T*)m_pData + (m_CurSize ++)) T;
293 T* AddRange(_In_ uint32_t count)
295 if (m_CurSize + count < m_CurSize)
297 m_hLastError = E_OUTOFMEMORY;
301 if (FAILED(Reserve(m_CurSize + count)))
304 T *pData = (T*)m_pData + m_CurSize;
305 for (
size_t i = 0; i < count; ++ i)
313 HRESULT Add(_In_
const T& var)
318 memcpy((T*)m_pData + m_CurSize, &var,
sizeof(T));
324 HRESULT AddRange(_In_reads_(count)
const T *pVar, _In_ uint32_t count)
326 if (m_CurSize + count < m_CurSize)
328 m_hLastError = E_OUTOFMEMORY;
332 if (FAILED(Reserve(m_CurSize + count)))
335 memcpy((T*)m_pData + m_CurSize, pVar, count *
sizeof(T));
341 HRESULT Insert(_In_
const T& var, _In_ uint32_t index)
343 assert(index < m_CurSize);
348 memmove((T*)m_pData + index + 1, (T*)m_pData + index, (m_CurSize - index) *
sizeof(T));
349 memcpy((T*)m_pData + index, &var,
sizeof(T));
355 HRESULT InsertRange(_In_reads_(count)
const T *pVar, _In_ uint32_t index, _In_ uint32_t count)
357 assert(index < m_CurSize);
359 if (m_CurSize + count < m_CurSize)
361 m_hLastError = E_OUTOFMEMORY;
365 if (FAILED(Reserve(m_CurSize + count)))
368 memmove((T*)m_pData + index + count, (T*)m_pData + index, (m_CurSize - index) *
sizeof(T));
369 memcpy((T*)m_pData + index, pVar, count *
sizeof(T));
375 inline T& operator[](_In_
size_t index)
377 assert(index < m_CurSize);
378 return ((T*)m_pData)[index];
382 void Delete(_In_ uint32_t index)
384 assert(index < m_CurSize);
387 memmove((T*)m_pData + index, (T*)m_pData + index + 1, (m_CurSize - index) *
sizeof(T));
391 void QuickDelete(_In_ uint32_t index)
393 assert(index < m_CurSize);
396 memcpy((T*)m_pData + index, (T*)m_pData + m_CurSize,
sizeof(T));
399 inline uint32_t GetSize()
const 404 inline T* GetData()
const 409 uint32_t FindIndexOf(_In_
const void *pEntry)
const 411 for (
size_t i = 0; i < m_CurSize; ++ i)
413 if (((T*)m_pData + i) == pEntry)
420 void Sort(
int (__cdecl *pfnCompare)(
const void *pElem1,
const void *pElem2))
422 qsort(m_pData, m_CurSize,
sizeof(T), pfnCompare);
436 for (
size_t i=0; i<m_CurSize; i++)
437 SAFE_DELETE(((T**)m_pData)[i]);
439 SAFE_DELETE_ARRAY(m_pData);
445 SAFE_DELETE_ARRAY(m_pData);
452 for (
size_t i = 0; i < m_CurSize; ++ i)
454 SAFE_DELETE(((T**)m_pData)[i]);
460 void Delete(_In_ uint32_t index)
462 assert(index < m_CurSize);
464 SAFE_DELETE(((T**)m_pData)[index]);
508 m_Value += other.m_Value;
510 if (m_Value < other.m_Value)
531 if (other.m_Value != 0)
533 if (m_Value > MaxValue / other.m_Value)
538 m_Value *= other.m_Value;
544 HRESULT GetValue(_Out_ T *pValue)
548 *pValue = uint32_t(-1);
577 HRESULT AddData(_In_reads_bytes_(bufferSize)
const void *pNewData, _In_ uint32_t bufferSize, _Outptr_
CDataBlock **ppBlock);
580 _Success_(
return !=
nullptr)
581 void* Allocate(_In_ uint32_t bufferSize, _Outptr_
CDataBlock **ppBlock);
583 void EnableAlignment();
603 uint32_t m_cAllocations;
607 HRESULT AddString(_In_z_ LPCSTR pString, _Inout_ uint32_t *pOffset);
610 HRESULT AddData(_In_reads_bytes_(bufferSize)
const void *pNewData, _In_ uint32_t bufferSize, _Inout_ uint32_t *pOffset);
614 void* Allocate(_In_ uint32_t bufferSize);
616 void EnableAlignment();
626 inline void* __cdecl
operator new(_In_
size_t s, _In_
CDataBlockStore &pAllocator)
629 assert( s <= 0xffffffff );
631 return pAllocator.Allocate( (uint32_t)s );
634 inline void __cdecl
operator delete(_In_opt_
void* p, _In_
CDataBlockStore &pAllocator)
636 UNREFERENCED_PARAMETER(p);
637 UNREFERENCED_PARAMETER(pAllocator);
645 #define HASH_MIX(a,b,c) \ 647 a -= b; a -= c; a ^= (c>>13); \ 648 b -= c; b -= a; b ^= (a<<8); \ 649 c -= a; c -= b; c ^= (b>>13); \ 650 a -= b; a -= c; a ^= (c>>12); \ 651 b -= c; b -= a; b ^= (a<<16); \ 652 c -= a; c -= b; c ^= (b>>5); \ 653 a -= b; a -= c; a ^= (c>>3); \ 654 b -= c; b -= a; b ^= (a<<10); \ 655 c -= a; c -= b; c ^= (b>>15); \ 658 static uint32_t ComputeHash(_In_reads_bytes_(cbToHash)
const uint8_t *pb, _In_ uint32_t cbToHash)
660 uint32_t cbLeft = cbToHash;
670 const uint32_t *pdw =
reinterpret_cast<const uint32_t *
>(pb);
685 case 11: c+=((uint32_t) pb[10] << 24);
686 case 10: c+=((uint32_t) pb[9] << 16);
687 case 9 : c+=((uint32_t) pb[8] << 8);
689 case 8 : b+=((uint32_t) pb[7] << 24);
690 case 7 : b+=((uint32_t) pb[6] << 16);
691 case 6 : b+=((uint32_t) pb[5] << 8);
693 case 4 : a+=((uint32_t) pb[3] << 24);
694 case 3 : a+=((uint32_t) pb[2] << 16);
695 case 2 : a+=((uint32_t) pb[1] << 8);
704 static uint32_t ComputeHashLower(_In_reads_bytes_(cbToHash)
const uint8_t *pb, _In_ uint32_t cbToHash)
706 uint32_t cbLeft = cbToHash;
716 for(
size_t i = 0; i < 12; i++ )
717 pbT[i] = (uint8_t)tolower(pb[i]);
719 uint32_t *pdw =
reinterpret_cast<uint32_t *
>(pbT);
733 for(
size_t i = 0; i < cbLeft; i++ )
734 pbT[i] = (uint8_t)tolower(pb[i]);
738 case 11: c+=((uint32_t) pbT[10] << 24);
739 case 10: c+=((uint32_t) pbT[9] << 16);
740 case 9 : c+=((uint32_t) pbT[8] << 8);
742 case 8 : b+=((uint32_t) pbT[7] << 24);
743 case 7 : b+=((uint32_t) pbT[6] << 16);
744 case 6 : b+=((uint32_t) pbT[5] << 8);
746 case 4 : a+=((uint32_t) pbT[3] << 24);
747 case 3 : a+=((uint32_t) pbT[2] << 16);
748 case 2 : a+=((uint32_t) pbT[1] << 8);
757 static uint32_t ComputeHash(_In_z_ LPCSTR pString)
759 return ComputeHash(reinterpret_cast<const uint8_t*>(pString), (uint32_t)strlen(pString));
768 static const uint32_t c_PrimeSizes[] =
800 template<
typename T,
bool (*pfnIsEqual)(const T &Data1, const T &Data2)>
814 uint32_t m_NumHashSlots;
815 uint32_t m_NumEntries;
816 bool m_bOwnHashEntryArray;
830 assert(pHashEntry != 0);
831 _Analysis_assume_(pHashEntry != 0);
832 return pHashEntry->Data;
837 assert(pHashEntry != 0);
838 _Analysis_assume_(pHashEntry != 0);
839 return pHashEntry->Hash;
844 m_rgpHashEntries(
nullptr),
847 m_bOwnHashEntryArray(
false)
855 uint32_t valuesMigrated = 0;
860 actualSize = pOther->m_NumHashSlots;
861 VN( rgpNewHashEntries =
new SHashEntry*[actualSize] );
863 ZeroMemory(rgpNewHashEntries,
sizeof(
SHashEntry*) * actualSize);
867 pOther->GetFirstEntry(&iter);
868 while (!pOther->PastEnd(&iter))
870 uint32_t index = iter.GetHash() % actualSize;
876 pOther->GetNextEntry(&nextIter);
882 pNewEntry->pNext = rgpNewHashEntries[index];
883 pNewEntry->Data = iter.pHashEntry->Data;
884 pNewEntry->Hash = iter.pHashEntry->Hash;
885 rgpNewHashEntries[index] = pNewEntry;
891 assert(valuesMigrated == pOther->m_NumEntries);
893 m_rgpHashEntries = rgpNewHashEntries;
894 m_NumHashSlots = actualSize;
895 m_NumEntries = pOther->m_NumEntries;
896 m_bOwnHashEntryArray =
true;
897 rgpNewHashEntries =
nullptr;
900 SAFE_DELETE_ARRAY( rgpNewHashEntries );
907 if (m_bOwnHashEntryArray)
909 SAFE_DELETE_ARRAY(m_rgpHashEntries);
910 m_bOwnHashEntryArray =
false;
917 for (
size_t i = 0; i < m_NumHashSlots; ++ i)
919 SHashEntry *pCurrentEntry = m_rgpHashEntries[i];
921 while (
nullptr != pCurrentEntry)
923 pTempEntry = pCurrentEntry->pNext;
924 SAFE_DELETE(pCurrentEntry);
925 pCurrentEntry = pTempEntry;
931 assert(m_NumEntries == 0);
939 static uint32_t GetNextHashTableSize(_In_ uint32_t DesiredSize)
942 for (
size_t i = 0; i < _countof(c_PrimeSizes); ++i )
944 if (c_PrimeSizes[i] >= DesiredSize)
946 return c_PrimeSizes[i];
956 HRESULT Grow(_In_ uint32_t DesiredSize,
957 _In_ uint32_t ProvidedArraySize = 0,
958 _In_reads_opt_(ProvidedArraySize)
void** ProvidedArray =
nullptr,
959 _In_
bool OwnProvidedArray =
false)
963 uint32_t valuesMigrated = 0;
966 VB( DesiredSize > m_NumHashSlots );
968 actualSize = GetNextHashTableSize(DesiredSize);
971 ProvidedArraySize >= actualSize)
973 rgpNewHashEntries =
reinterpret_cast<SHashEntry**
>(ProvidedArray);
977 OwnProvidedArray =
true;
979 VN( rgpNewHashEntries =
new SHashEntry*[actualSize] );
982 ZeroMemory(rgpNewHashEntries,
sizeof(
SHashEntry*) * actualSize);
986 GetFirstEntry(&iter);
987 while (!PastEnd(&iter))
989 uint32_t index = iter.GetHash() % actualSize;
995 GetNextEntry(&nextIter);
998 iter.pHashEntry->pNext = rgpNewHashEntries[index];
999 rgpNewHashEntries[index] = iter.pHashEntry;
1005 assert(valuesMigrated == m_NumEntries);
1008 m_rgpHashEntries = rgpNewHashEntries;
1009 m_NumHashSlots = actualSize;
1010 m_bOwnHashEntryArray = OwnProvidedArray;
1019 if (m_NumEntries >= m_NumHashSlots)
1022 return Grow(m_NumEntries * 2 + 1);
1028 void PrintHashTableStats()
1030 if (m_NumHashSlots == 0)
1032 DPF(0,
"Uninitialized hash table!");
1036 float variance = 0.0f;
1037 float mean = (float)m_NumEntries / (
float)m_NumHashSlots;
1038 uint32_t unusedSlots = 0;
1040 DPF(0,
"Hash table slots: %d, Entries in table: %d", m_NumHashSlots, m_NumEntries);
1042 for (
size_t i = 0; i < m_NumHashSlots; ++ i)
1044 uint32_t entries = 0;
1045 SHashEntry *pCurrentEntry = m_rgpHashEntries[i];
1047 while (
nullptr != pCurrentEntry)
1049 SHashEntry *pCurrentEntry2 = m_rgpHashEntries[i];
1052 while (pCurrentEntry2 != pCurrentEntry)
1054 if (pCurrentEntry->Hash == pCurrentEntry2->Hash)
1056 if (pfnIsEqual(pCurrentEntry->Data, pCurrentEntry2->Data))
1059 DPF(0,
"Duplicate entry (identical hash, identical data) found!");
1063 DPF(0,
"Hash collision (hash: %d)", pCurrentEntry->Hash);
1066 pCurrentEntry2 = pCurrentEntry2->pNext;
1069 pCurrentEntry = pCurrentEntry->pNext;
1079 variance += (float)entries * (
float)entries / mean;
1082 variance /= std::max(1.0f, (m_NumHashSlots - 1));
1083 variance -= (mean * mean);
1085 DPF(0,
"Mean number of entries per slot: %f, Standard deviation: %f, Unused slots; %d", mean, variance, unusedSlots);
1090 HRESULT FindValueWithHash(_In_ T Data, _In_ uint32_t Hash, _Out_
CIterator *pIterator)
1092 assert(m_NumHashSlots > 0);
1094 uint32_t index = Hash % m_NumHashSlots;
1095 SHashEntry *pEntry = m_rgpHashEntries[index];
1096 while (
nullptr != pEntry)
1098 if (Hash == pEntry->Hash && pfnIsEqual(pEntry->Data, Data))
1100 pIterator->ppHashSlot = m_rgpHashEntries + index;
1101 pIterator->pHashEntry = pEntry;
1104 pEntry = pEntry->pNext;
1110 HRESULT FindFirstMatchingValue(_In_ uint32_t Hash, _Out_
CIterator *pIterator)
1112 assert(m_NumHashSlots > 0);
1114 uint32_t index = Hash % m_NumHashSlots;
1115 SHashEntry *pEntry = m_rgpHashEntries[index];
1116 while (
nullptr != pEntry)
1118 if (Hash == pEntry->Hash)
1120 pIterator->ppHashSlot = m_rgpHashEntries + index;
1121 pIterator->pHashEntry = pEntry;
1124 pEntry = pEntry->pNext;
1130 HRESULT AddValueWithHash(_In_ T Data, _In_ uint32_t Hash)
1134 assert(m_NumHashSlots > 0);
1137 uint32_t index = Hash % m_NumHashSlots;
1140 pHashEntry->pNext = m_rgpHashEntries[index];
1141 pHashEntry->Data = Data;
1142 pHashEntry->Hash = Hash;
1143 m_rgpHashEntries[index] = pHashEntry;
1156 void GetFirstEntry(_Out_
CIterator *pIterator)
1158 SHashEntry **ppEnd = m_rgpHashEntries + m_NumHashSlots;
1159 pIterator->ppHashSlot = m_rgpHashEntries;
1160 while (pIterator->ppHashSlot < ppEnd)
1162 if (
nullptr != *(pIterator->ppHashSlot))
1164 pIterator->pHashEntry = *(pIterator->ppHashSlot);
1167 ++ pIterator->ppHashSlot;
1171 bool PastEnd(_Inout_
CIterator *pIterator)
1173 SHashEntry **ppEnd = m_rgpHashEntries + m_NumHashSlots;
1174 assert(pIterator->ppHashSlot >= m_rgpHashEntries && pIterator->ppHashSlot <= ppEnd);
1175 return (pIterator->ppHashSlot == ppEnd);
1178 void GetNextEntry(_Inout_
CIterator *pIterator)
1180 SHashEntry **ppEnd = m_rgpHashEntries + m_NumHashSlots;
1181 assert(pIterator->ppHashSlot >= m_rgpHashEntries && pIterator->ppHashSlot <= ppEnd);
1182 assert(pIterator->pHashEntry != 0);
1183 _Analysis_assume_(pIterator->pHashEntry != 0);
1185 pIterator->pHashEntry = pIterator->pHashEntry->pNext;
1186 if (
nullptr != pIterator->pHashEntry)
1191 ++ pIterator->ppHashSlot;
1192 while (pIterator->ppHashSlot < ppEnd)
1194 pIterator->pHashEntry = *(pIterator->ppHashSlot);
1195 if (
nullptr != pIterator->pHashEntry)
1199 ++ pIterator->ppHashSlot;
1204 void RemoveEntry(_Inout_
CIterator *pIterator)
1208 SHashEntry **ppEnd = m_rgpHashEntries + m_NumHashSlots;
1210 assert(pIterator && !PastEnd(pIterator));
1211 ppPrev = pIterator->ppHashSlot;
1215 if (pTemp == pIterator->pHashEntry)
1217 *ppPrev = pTemp->pNext;
1218 pIterator->ppHashSlot = ppEnd;
1222 ppPrev = &pTemp->pNext;
1223 pTemp = pTemp->pNext;
1236 template<
typename T,
bool (*pfnIsEqual)(const T &Data1, const T &Data2)>
1244 m_pPrivateHeap(
nullptr)
1263 assert(
nullptr == m_pPrivateHeap);
1264 m_pPrivateHeap = pPrivateHeap;
1268 HRESULT AddValueWithHash(_In_ T Data, _In_ uint32_t Hash)
1272 assert(m_pPrivateHeap);
1273 _Analysis_assume_(m_pPrivateHeap);
1274 assert(m_NumHashSlots > 0);
1277 uint32_t index = Hash % m_NumHashSlots;
1279 VN( pHashEntry =
new(*m_pPrivateHeap)
SHashEntry );
1280 pHashEntry->pNext = m_rgpHashEntries[index];
1281 pHashEntry->Data = Data;
1282 pHashEntry->Hash = Hash;
1283 m_rgpHashEntries[index] = pHashEntry;
Definition: d3dxGlobal.h:17
Definition: d3dxGlobal.h:142
Definition: d3dxGlobal.h:592
Definition: d3dxGlobal.h:429
Definition: d3dxGlobal.h:565
Definition: d3dxGlobal.cpp:19
Definition: d3dxGlobal.h:98
Definition: d3dxGlobal.h:819
Definition: d3dxGlobal.h:801
Definition: d3dxGlobal.h:1237
Definition: d3dxGlobal.h:474
Definition: d3dxGlobal.h:805