Пример #1
0
R *X(taint)(R *p, int s)
{
     if (((unsigned)s * sizeof(R)) % ALIGNMENT)
	  p = (R *) (PTRINT(p) | TAINT_BIT);
     if (((unsigned)s * sizeof(R)) % ALIGNMENTA)
	  p = (R *) (PTRINT(p) | TAINT_BITA);
     return p;
}
Пример #2
0
	/**
	 * Writes the data for a single mip-level into a destination buffer.
	 * @param FaceIndex		The index of the face of the mip-level to read.
	 * @param MipIndex		The index of the mip-level to read.
	 * @param Dest			The address of the destination buffer to receive the mip-level's data.
	 * @param DestPitch		Number of bytes per row
	 */
	void GetData( int32 FaceIndex, int32 MipIndex, void* Dest, uint32 DestPitch )
	{
		check( MipData[FaceIndex][MipIndex] );

		// for platforms that returned 0 pitch from Lock, we need to just use the bulk data directly, never do 
		// runtime block size checking, conversion, or the like
		if (DestPitch == 0)
		{
			FMemory::Memcpy(Dest, MipData[FaceIndex][MipIndex], Owner->PlatformData->Mips[MipIndex].BulkData.GetBulkDataSize() / 6);
		}
		else
		{
			EPixelFormat PixelFormat = Owner->GetPixelFormat();
			uint32 NumRows = 0;
			uint32 SrcPitch = 0;
			uint32 BlockSizeX = GPixelFormats[PixelFormat].BlockSizeX;	// Block width in pixels
			uint32 BlockSizeY = GPixelFormats[PixelFormat].BlockSizeY;	// Block height in pixels
			uint32 BlockBytes = GPixelFormats[PixelFormat].BlockBytes;

			FIntPoint MipExtent = CalcMipMapExtent(Owner->GetSizeX(), Owner->GetSizeY(), PixelFormat, MipIndex);

			uint32 NumColumns = (MipExtent.X + BlockSizeX - 1) / BlockSizeX;	// Num-of columns in the source data (in blocks)
			NumRows    = (MipExtent.Y + BlockSizeY - 1) / BlockSizeY;	// Num-of rows in the source data (in blocks)
			SrcPitch   = NumColumns * BlockBytes;		// Num-of bytes per row in the source data
				
			SIZE_T MipSizeInBytes = CalcTextureMipMapSize(MipExtent.X, MipExtent.Y, PixelFormat, 0);

			if (SrcPitch == DestPitch)
			{

				// Copy data, not taking into account stride!
				FMemory::Memcpy(Dest, MipData[FaceIndex][MipIndex], MipSizeInBytes);
			}
			else
			{
				// Copy data, taking the stride into account!
				uint8 *Src = (uint8*) MipData[FaceIndex][MipIndex];
				uint8 *Dst = (uint8*) Dest;
				for ( uint32 Row=0; Row < NumRows; ++Row )
				{
					FMemory::Memcpy( Dst, Src, SrcPitch );
					Src += SrcPitch;
					Dst += DestPitch;
				}
				check( (PTRINT(Src) - PTRINT(MipData[FaceIndex][MipIndex])) == PTRINT(MipSizeInBytes) );
			}
		}

		FMemory::Free( MipData[FaceIndex][MipIndex] );
		MipData[FaceIndex][MipIndex] = NULL;
	}
/**
 *	Opens a file. (Thread-safe)
 *	If opened for write, it will create any necessary directory structure.
 *
 *	@param Filename		Full path to the file
 *	@param Flags		A combination of EFileOpenFlags, specifying read/write access.
 *	@return				File handle
 **/
FFileHandle FFileManagerWindows::InternalFileOpen( const TCHAR* Filename, DWORD Flags )
{
	DWORD AccessFlags = (Flags & IO_READ) ? GENERIC_READ : 0;
	DWORD CreateFlags = 0;
	if ( Flags & IO_WRITE )
	{
		MakeDirectory(*FFilename(Filename).GetPath(), TRUE);
		AccessFlags |= GENERIC_WRITE;
		CreateFlags = (Flags & IO_APPEND) ? OPEN_ALWAYS : CREATE_NEW;
	}
	else
	{
		CreateFlags = OPEN_EXISTING;
	}

	HANDLE WinHandle = CreateFile( Filename, AccessFlags, FILE_SHARE_READ, NULL, CreateFlags, FILE_ATTRIBUTE_NORMAL, NULL );
	if ( WinHandle == INVALID_HANDLE_VALUE )
    {
        WinHandle = (HANDLE) INDEX_NONE;
    }
	else if ( Flags & IO_APPEND )
	{
		SetFilePointer( WinHandle, 0, NULL, FILE_END );
	}
	FFileHandle Handle( PTRINT(WinHandle), 0 );
	return Handle;
}
Пример #4
0
/**
 * Tries to reallocate texture memory in-place (without relocating),
 * by adjusting the base address of the allocation but keeping the end address the same.
 *
 * @param	OldBaseAddress	Pointer to the original allocation
 * @param	NewBaseAddress	New desired baseaddress for the allocation (adjusting the size so the end stays the same)
 * @returns	TRUE if it succeeded
 **/
UBOOL FBestFitAllocator::Reallocate( void* OldBaseAddress, void* NewBaseAddress )
{
	SCOPE_SECONDS_COUNTER(TimeSpentInAllocator);

	// Look up pointer in TMap.
	FMemoryChunk* MatchingChunk = PointerToChunkMap.FindRef( PTRINT(OldBaseAddress) );
	check( MatchingChunk && PTRINT(OldBaseAddress) == PTRINT(MatchingChunk->Base) );

	INT MemoryAdjustment = Abs<INT>(PTRINT(NewBaseAddress) - PTRINT(OldBaseAddress));

	// Are we growing the allocation?
	if ( PTRINT(NewBaseAddress) < PTRINT(OldBaseAddress) )
	{
		// Is there enough free memory immediately before this chunk?
		FMemoryChunk* PrevChunk = MatchingChunk->PreviousChunk;
		if ( PrevChunk && PrevChunk->bIsAvailable && PrevChunk->Size >= MemoryAdjustment )
		{
			PointerToChunkMap.Remove( PTRINT(OldBaseAddress) );

			// Shrink the previous and grow the current chunk.
			PrevChunk->Size -= MemoryAdjustment;
			MatchingChunk->Base -= MemoryAdjustment;
			MatchingChunk->Size += MemoryAdjustment;

			check(PTRINT(NewBaseAddress) == PTRINT(MatchingChunk->Base));
			PointerToChunkMap.Set( PTRINT(NewBaseAddress), MatchingChunk );

			if ( PrevChunk->Size == 0 )
			{
				delete PrevChunk;
			}

			// Update usage stats in a thread safe way.
			appInterlockedAdd( &AllocatedMemorySize, +MemoryAdjustment );
			appInterlockedAdd( &AvailableMemorySize, -MemoryAdjustment );
			return TRUE;
		}
	}
	else
	{
		// We're shrinking the allocation.
		check( MemoryAdjustment <= MatchingChunk->Size );

		FMemoryChunk* PrevChunk = MatchingChunk->PreviousChunk;
		if ( PrevChunk )
		{
			// Shrink the current chunk.
			MatchingChunk->Base += MemoryAdjustment;
			MatchingChunk->Size -= MemoryAdjustment;

			// Grow the previous chunk.
			INT OriginalPrevSize = PrevChunk->Size;
			PrevChunk->Size += MemoryAdjustment;

			// If the previous chunk was "in use", split it and insert a 2nd free chunk.
			if ( !PrevChunk->bIsAvailable )
			{
				Split( PrevChunk, OriginalPrevSize );
			}
		}
		else
		{
			// This was the first chunk, split it.
			Split( MatchingChunk, MemoryAdjustment );

			// We're going to use the new chunk. Mark it as "used memory".
			MatchingChunk = MatchingChunk->NextChunk;
			MatchingChunk->UnlinkFree();

			// Make the original chunk "free memory".
			FreeChunk( MatchingChunk->PreviousChunk );
		}

		check(PTRINT(NewBaseAddress) == PTRINT(MatchingChunk->Base));
		PointerToChunkMap.Remove( PTRINT(OldBaseAddress) );
		PointerToChunkMap.Set( PTRINT(NewBaseAddress), MatchingChunk );

		// Update usage stats in a thread safe way.
		appInterlockedAdd( &AllocatedMemorySize, -MemoryAdjustment );
		appInterlockedAdd( &AvailableMemorySize, +MemoryAdjustment );
		return TRUE;
	}
	return FALSE;
}
Пример #5
0
/* join the taint of two pointers that are supposed to be
   the same modulo the taint */
R *X(join_taint)(R *p1, R *p2)
{
     A(UNTAINT(p1) == UNTAINT(p2));
     return (R *)(PTRINT(p1) | PTRINT(p2));
}