Exemplo n.º 1
0
void FD3D11DynamicRHI::Shutdown()
{
	check(IsInGameThread() && IsInRenderingThread());  // require that the render thread has been shut down

	// Cleanup the D3D device.
	CleanupD3DDevice();

	// Release buffered timestamp queries
	GPUProfilingData.FrameTiming.ReleaseResource();

	// Release the buffer of zeroes.
	FMemory::Free(ZeroBuffer);
	ZeroBuffer = NULL;
	ZeroBufferSize = 0;
}
Exemplo n.º 2
0
void FD3D11DynamicRHI::InitD3DDevice()
{
	check( IsInGameThread() );

	// Wait for the rendering thread to go idle.
	SCOPED_SUSPEND_RENDERING_THREAD(false);

	// If the device we were using has been removed, release it and the resources we created for it.
	if(bDeviceRemoved)
	{
		UE_LOG(LogD3D11RHI, Log, TEXT("bDeviceRemoved"));
		check(Direct3DDevice);

		HRESULT hRes = Direct3DDevice->GetDeviceRemovedReason();

		const TCHAR* Reason = TEXT("?");
		switch(hRes)
		{
			case DXGI_ERROR_DEVICE_HUNG:			Reason = TEXT("HUNG"); break;
			case DXGI_ERROR_DEVICE_REMOVED:			Reason = TEXT("REMOVED"); break;
			case DXGI_ERROR_DEVICE_RESET:			Reason = TEXT("RESET"); break;
			case DXGI_ERROR_DRIVER_INTERNAL_ERROR:	Reason = TEXT("INTERNAL_ERROR"); break;
			case DXGI_ERROR_INVALID_CALL:			Reason = TEXT("INVALID_CALL"); break;
		}

		bDeviceRemoved = false;

		// Cleanup the D3D device.
		CleanupD3DDevice();

		// We currently don't support removed devices because FTexture2DResource can't recreate its RHI resources from scratch.
		// We would also need to recreate the viewport swap chains from scratch.
		UE_LOG(LogD3D11RHI, Fatal, TEXT("The Direct3D 11 device that was being used has been removed (Error: %d '%s').  Please restart the game."), hRes, Reason);
	}

	// If we don't have a device yet, either because this is the first viewport, or the old device was removed, create a device.
	if(!Direct3DDevice)
	{
		UE_LOG(LogD3D11RHI, Log, TEXT("!Direct3DDevice"));
		check(!GIsRHIInitialized);

		// Clear shadowed shader resources.
		ClearState();

		// Determine the adapter and device type to use.
		TRefCountPtr<IDXGIAdapter> Adapter;
		
		// In Direct3D 11, if you are trying to create a hardware or a software device, set pAdapter != NULL which constrains the other inputs to be:
		//		DriverType must be D3D_DRIVER_TYPE_UNKNOWN 
		//		Software must be NULL. 
		D3D_DRIVER_TYPE DriverType = D3D_DRIVER_TYPE_UNKNOWN;	

		uint32 DeviceFlags = D3D11RHI_ShouldAllowAsyncResourceCreation() ? 0 : D3D11_CREATE_DEVICE_SINGLETHREADED;

		// Use a debug device if specified on the command line.
		const bool bWithD3DDebug = D3D11RHI_ShouldCreateWithD3DDebug();

		if (bWithD3DDebug)
		{
			DeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;

			UE_LOG(LogD3D11RHI, Log, TEXT("InitD3DDevice: -D3DDebug = %s"), bWithD3DDebug ? TEXT("on") : TEXT("off"));
		}

		GTexturePoolSize = 0;

		TRefCountPtr<IDXGIAdapter> EnumAdapter;

		if(DXGIFactory1->EnumAdapters(ChosenAdapter,EnumAdapter.GetInitReference()) != DXGI_ERROR_NOT_FOUND)
		{
			if (EnumAdapter)// && EnumAdapter->CheckInterfaceSupport(__uuidof(ID3D11Device),NULL) == S_OK)
			{
				DXGI_ADAPTER_DESC AdapterDesc;
				if (SUCCEEDED(EnumAdapter->GetDesc(&AdapterDesc)))
				{
					Adapter = EnumAdapter;

					GRHIAdapterName = AdapterDesc.Description;
					GRHIVendorId = AdapterDesc.VendorId;

					// Issue: 32bit windows doesn't report 64bit value, we take what we get.
					FD3D11GlobalStats::GDedicatedVideoMemory = int64(AdapterDesc.DedicatedVideoMemory);
					FD3D11GlobalStats::GDedicatedSystemMemory = int64(AdapterDesc.DedicatedSystemMemory);
					FD3D11GlobalStats::GSharedSystemMemory = int64(AdapterDesc.SharedSystemMemory);

					// Total amount of system memory, clamped to 8 GB
					int64 TotalPhysicalMemory = FMath::Min(int64(FPlatformMemory::GetConstants().TotalPhysicalGB), 8ll) * (1024ll * 1024ll * 1024ll);

					// Consider 50% of the shared memory but max 25% of total system memory.
					int64 ConsideredSharedSystemMemory = FMath::Min( FD3D11GlobalStats::GSharedSystemMemory / 2ll, TotalPhysicalMemory / 4ll );

					FD3D11GlobalStats::GTotalGraphicsMemory = 0;
					if ( IsRHIDeviceIntel() )
					{
						// It's all system memory.
						FD3D11GlobalStats::GTotalGraphicsMemory = FD3D11GlobalStats::GDedicatedVideoMemory;
						FD3D11GlobalStats::GTotalGraphicsMemory += FD3D11GlobalStats::GDedicatedSystemMemory;
						FD3D11GlobalStats::GTotalGraphicsMemory += ConsideredSharedSystemMemory;
					}
					else if ( FD3D11GlobalStats::GDedicatedVideoMemory >= 200*1024*1024 )
					{
						// Use dedicated video memory, if it's more than 200 MB
						FD3D11GlobalStats::GTotalGraphicsMemory = FD3D11GlobalStats::GDedicatedVideoMemory;
					}
					else if ( FD3D11GlobalStats::GDedicatedSystemMemory >= 200*1024*1024 )
					{
						// Use dedicated system memory, if it's more than 200 MB
						FD3D11GlobalStats::GTotalGraphicsMemory = FD3D11GlobalStats::GDedicatedSystemMemory;
					}
					else if ( FD3D11GlobalStats::GSharedSystemMemory >= 400*1024*1024 )
					{
						// Use some shared system memory, if it's more than 400 MB
						FD3D11GlobalStats::GTotalGraphicsMemory = ConsideredSharedSystemMemory;
					}
					else
					{
						// Otherwise consider 25% of total system memory for graphics.
						FD3D11GlobalStats::GTotalGraphicsMemory = TotalPhysicalMemory / 4ll;
					}

					if ( sizeof(SIZE_T) < 8 )
					{
						// Clamp to 1 GB if we're less than 64-bit
						FD3D11GlobalStats::GTotalGraphicsMemory = FMath::Min( FD3D11GlobalStats::GTotalGraphicsMemory, 1024ll * 1024ll * 1024ll );
					}
					else
					{
						// Clamp to 1.9 GB if we're 64-bit
						FD3D11GlobalStats::GTotalGraphicsMemory = FMath::Min( FD3D11GlobalStats::GTotalGraphicsMemory, 1945ll * 1024ll * 1024ll );
					}

					if ( GPoolSizeVRAMPercentage > 0 )
					{
						float PoolSize = float(GPoolSizeVRAMPercentage) * 0.01f * float(FD3D11GlobalStats::GTotalGraphicsMemory);

						// Truncate GTexturePoolSize to MB (but still counted in bytes)
						GTexturePoolSize = int64(FGenericPlatformMath::TruncToFloat(PoolSize / 1024.0f / 1024.0f)) * 1024 * 1024;

						UE_LOG(LogRHI,Log,TEXT("Texture pool is %llu MB (%d%% of %llu MB)"),
							GTexturePoolSize / 1024 / 1024,
							GPoolSizeVRAMPercentage,
							FD3D11GlobalStats::GTotalGraphicsMemory / 1024 / 1024);
					}

					const bool bIsPerfHUD = !FCString::Stricmp(AdapterDesc.Description,TEXT("NVIDIA PerfHUD"));

					if(bIsPerfHUD)
					{
						DriverType =  D3D_DRIVER_TYPE_REFERENCE;
					}
				}
				else
				{
					check(!"Internal error, GetDesc() failed but before it worked")
				}
			}
		}
		else
		{