Files
UnrealEngineUWP/Engine/Shaders/Private/HashTable.ush
simon tovey e603e3db72 Fixing HWRT collisions on console.
- Platform specific wrapper for vfx RT code to access payload and trace result structures better on each platform.

- Moved hash table to use RWBuffers instead of RWStructuredBuffers.
   - Unclear why right now but when using structured buffers it seems like the format was interperted wrong somehow so only the first byte was ever read/written to the buffer. Causeing havok with the rest of the hash table setup.
   - Malformed hash tables also can cause GPU hangs so added safety code for that.

Misc
- Adding transitions after buffer clears.
- Fixed bad define in #if

#rb Stu.Mckenna, Yuriy.ODonnell
#preflight 611b8cc15e737200017c5f7f

#ROBOMERGE-SOURCE: CL 17189263 via CL 17189315
#ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v855-17104924)

[CL 17189333 by simon tovey in ue5-release-engine-test branch]
2021-08-17 07:45:28 -04:00

109 lines
2.0 KiB
Plaintext

// Copyright Epic Games, Inc. All Rights Reserved.
uint MurmurAdd( uint Hash, uint Element )
{
Element *= 0xcc9e2d51;
Element = ( Element << 15 ) | ( Element >> (32 - 15) );
Element *= 0x1b873593;
Hash ^= Element;
Hash = ( Hash << 13 ) | ( Hash >> (32 - 13) );
Hash = Hash * 5 + 0xe6546b64;
return Hash;
}
uint MurmurMix( uint Hash )
{
Hash ^= Hash >> 16;
Hash *= 0x85ebca6b;
Hash ^= Hash >> 13;
Hash *= 0xc2b2ae35;
Hash ^= Hash >> 16;
return Hash;
}
// Linear probing hash table
Buffer< uint > HashTable;
RWBuffer< uint > RWHashTable;
uint HashTableSize;
// Returns true if key is added for the first time.
// Index output is the hash table bucket this key is stored in.
bool HashTableAdd( uint Key, out uint Index )
{
// Zero is reserved as invalid
Key++;
uint NumLoops = 0;
LOOP
[allow_uav_condition]
for(Index = MurmurMix(Key); ; Index++ )
{
//Belt and braces safety code to prevent inf loops if tables are malformed.
if(++NumLoops > HashTableSize)
{
break;
}
//Index &= HashTableSize - 1;
Index = Index % HashTableSize;
uint StoredKey = RWHashTable[ Index ];
if( StoredKey != Key )
{
if( StoredKey != 0 )
continue;
uint PrevKey;
InterlockedCompareExchange( RWHashTable[ Index ], 0, Key, PrevKey );
if( PrevKey == 0 )
return true;
else if( PrevKey != Key )
continue;
}
break;
}
return false;
}
// Returns true if key is found.
// Index output is the hash table bucket this key is stored in if found.
bool HashTableFind( uint Key, out uint Index )
{
// Zero is reserved as invalid
Key++;
uint NumLoops = 0;
LOOP
[allow_uav_condition]
for( Index = MurmurMix( Key );; Index++ )
{
//Belt and braces safety code to prevent inf loops if tables are malformed.
if (++NumLoops > HashTableSize)
{
break;
}
//Index &= HashTableSize - 1;
Index = Index % HashTableSize;
uint StoredKey = HashTable[ Index ];
if( StoredKey != Key )
{
if( StoredKey != 0 )
continue;
}
else
{
return true;
}
break;
}
return false;
}