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; }
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 {