From 90f586383a3a23505acebf8c44954cbf892b3d71 Mon Sep 17 00:00:00 2001 From: Triang3l Date: Tue, 2 Oct 2018 17:10:04 +0300 Subject: [PATCH] [D3D12] Make tiled resources optional - not available on old Intel HD Graphics --- src/xenia/gpu/d3d12/shared_memory.cc | 26 ++++++++- src/xenia/gpu/d3d12/shared_memory.h | 2 + src/xenia/ui/d3d12/d3d12_api.cc | 16 ------ src/xenia/ui/d3d12/d3d12_api.h | 4 -- src/xenia/ui/d3d12/d3d12_provider.cc | 84 +++++++++++++--------------- src/xenia/ui/d3d12/d3d12_provider.h | 3 +- 6 files changed, 65 insertions(+), 70 deletions(-) delete mode 100644 src/xenia/ui/d3d12/d3d12_api.cc diff --git a/src/xenia/gpu/d3d12/shared_memory.cc b/src/xenia/gpu/d3d12/shared_memory.cc index 6c2b63063..bfacf5ea1 100644 --- a/src/xenia/gpu/d3d12/shared_memory.cc +++ b/src/xenia/gpu/d3d12/shared_memory.cc @@ -9,6 +9,8 @@ #include "xenia/gpu/d3d12/shared_memory.h" +#include + #include #include @@ -20,6 +22,12 @@ #include "xenia/gpu/d3d12/d3d12_command_processor.h" #include "xenia/ui/d3d12/d3d12_util.h" +DEFINE_bool(d3d12_tiled_resources, true, + "Enable tiled resources for shared memory emulation. Disabling " + "them greatly increases video memory usage - a 512 MB buffer is " + "created - but allows graphics debuggers that don't support tiled " + "resources to work."); + namespace xe { namespace gpu { namespace d3d12 { @@ -45,7 +53,7 @@ bool SharedMemory::Initialize() { ui::d3d12::util::FillBufferResourceDesc( buffer_desc, kBufferSize, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); buffer_state_ = D3D12_RESOURCE_STATE_COPY_DEST; - if (FLAGS_d3d12_tiled_resources) { + if (AreTiledResourcesUsed()) { if (FAILED(device->CreateReservedResource( &buffer_desc, buffer_state_, nullptr, IID_PPV_ARGS(&buffer_)))) { XELOGE("Shared memory: Failed to create the 512 MB tiled buffer"); @@ -53,6 +61,10 @@ bool SharedMemory::Initialize() { return false; } } else { + XELOGGPU( + "Direct3D 12 tiled resources are not used for shared memory " + "emulation - video memory usage may increase significantly " + "because a full 512 MB buffer will be created!"); if (FAILED(device->CreateCommittedResource( &ui::d3d12::util::kHeapPropertiesDefault, D3D12_HEAP_FLAG_NONE, &buffer_desc, buffer_state_, nullptr, IID_PPV_ARGS(&buffer_)))) { @@ -91,7 +103,7 @@ void SharedMemory::Shutdown() { buffer_ = nullptr; } - if (FLAGS_d3d12_tiled_resources) { + if (AreTiledResourcesUsed()) { for (uint32_t i = 0; i < xe::countof(heaps_); ++i) { if (heaps_[i] != nullptr) { heaps_[i]->Release(); @@ -197,7 +209,7 @@ bool SharedMemory::MakeTilesResident(uint32_t start, uint32_t length) { return false; } - if (!FLAGS_d3d12_tiled_resources) { + if (!AreTiledResourcesUsed()) { return true; } @@ -353,6 +365,14 @@ void SharedMemory::RangeWrittenByGPU(uint32_t start, uint32_t length) { MakeRangeValid(page_first, page_last - page_first + 1); } +bool SharedMemory::AreTiledResourcesUsed() const { + if (!FLAGS_d3d12_tiled_resources) { + return false; + } + auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); + return provider->GetTiledResourcesTier() >= 1; +} + void SharedMemory::MakeRangeValid(uint32_t valid_page_first, uint32_t valid_page_count) { if (valid_page_first >= page_count_ || valid_page_count == 0) { diff --git a/src/xenia/gpu/d3d12/shared_memory.h b/src/xenia/gpu/d3d12/shared_memory.h index accd1bb2d..3713ef805 100644 --- a/src/xenia/gpu/d3d12/shared_memory.h +++ b/src/xenia/gpu/d3d12/shared_memory.h @@ -93,6 +93,8 @@ class SharedMemory { void CreateRawUAV(D3D12_CPU_DESCRIPTOR_HANDLE handle); private: + bool AreTiledResourcesUsed() const; + // Mark the memory range as updated and protect it. The validity mutex must // NOT be held when calling!!! void MakeRangeValid(uint32_t valid_page_first, uint32_t valid_page_count); diff --git a/src/xenia/ui/d3d12/d3d12_api.cc b/src/xenia/ui/d3d12/d3d12_api.cc deleted file mode 100644 index 142701520..000000000 --- a/src/xenia/ui/d3d12/d3d12_api.cc +++ /dev/null @@ -1,16 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2018 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include "xenia/ui/d3d12/d3d12_api.h" - -DEFINE_bool(d3d12_tiled_resources, true, - "Enable tiled resources for shared memory emulation. Disabling " - "them greatly increases video memory usage - a 512 MB buffer is " - "created - but allows graphics debuggers that don't support tiled " - "resources to work."); diff --git a/src/xenia/ui/d3d12/d3d12_api.h b/src/xenia/ui/d3d12/d3d12_api.h index e1d3149d5..b3528a3f9 100644 --- a/src/xenia/ui/d3d12/d3d12_api.h +++ b/src/xenia/ui/d3d12/d3d12_api.h @@ -10,8 +10,6 @@ #ifndef XENIA_UI_D3D12_D3D12_API_H_ #define XENIA_UI_D3D12_D3D12_API_H_ -#include - // This must be included before D3D and DXGI for things like NOMINMAX. #include "xenia/base/platform_win.h" @@ -21,6 +19,4 @@ #define XELOGD3D XELOGI -DECLARE_bool(d3d12_tiled_resources); - #endif // XENIA_UI_D3D12_D3D12_API_H_ diff --git a/src/xenia/ui/d3d12/d3d12_provider.cc b/src/xenia/ui/d3d12/d3d12_provider.cc index a840118f5..4fd7093de 100644 --- a/src/xenia/ui/d3d12/d3d12_provider.cc +++ b/src/xenia/ui/d3d12/d3d12_provider.cc @@ -15,7 +15,8 @@ #include "xenia/ui/d3d12/d3d12_context.h" DEFINE_bool(d3d12_debug, false, "Enable Direct3D 12 and DXGI debug layer."); -DEFINE_int32(d3d12_adapter_index, -1, "Index of the DXGI adapter to use. " +DEFINE_int32(d3d12_adapter_index, -1, + "Index of the DXGI adapter to use. " "-1 for any physical adapter, -2 for WARP software rendering."); namespace xe { @@ -29,7 +30,7 @@ std::unique_ptr D3D12Provider::Create(Window* main_window) { "Unable to initialize Direct3D 12 graphics subsystem.\n" "\n" "Ensure that you have the latest drivers for your GPU and it supports " - "Direct3D 12 feature level 11_0 and tiled resources tier 1.\n" + "Direct3D 12 feature level 11_0.\n" "\n" "See http://xenia.jp/faq/ for more information and a list of supported " "GPUs."); @@ -79,44 +80,44 @@ bool D3D12Provider::Initialize() { // TODO(Triang3l): Log adapter info (contains a wide string). uint32_t adapter_index = 0; IDXGIAdapter1* adapter = nullptr; - ID3D12Device* device = nullptr; while (dxgi_factory->EnumAdapters1(adapter_index, &adapter) == S_OK) { DXGI_ADAPTER_DESC1 adapter_desc; if (SUCCEEDED(adapter->GetDesc1(&adapter_desc))) { if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, - IID_PPV_ARGS(&device)))) { - if (IsDeviceSupported(device)) { - if (FLAGS_d3d12_adapter_index >= 0) { - if (adapter_index == FLAGS_d3d12_adapter_index) { - break; - } - } else if (FLAGS_d3d12_adapter_index == -2) { - if (adapter_desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { - break; - } - } else { - if (!(adapter_desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)) { - break; - } + _uuidof(ID3D12Device), nullptr))) { + if (FLAGS_d3d12_adapter_index >= 0) { + if (adapter_index == FLAGS_d3d12_adapter_index) { + break; + } + } else if (FLAGS_d3d12_adapter_index == -2) { + if (adapter_desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { + break; + } + } else { + if (!(adapter_desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)) { + break; } } - device->Release(); - device = nullptr; } } adapter->Release(); adapter = nullptr; ++adapter_index; } - if (adapter != nullptr) { - adapter->Release(); - } - if (device == nullptr) { - XELOGE("Failed to get an adapter supporting Direct3D feature level 11_0 " - "with required options, or failed to create a Direct3D 12 device."); + if (adapter == nullptr) { + XELOGE("Failed to get an adapter supporting Direct3D feature level 11_0."); dxgi_factory->Release(); return false; } + ID3D12Device* device; + if (FAILED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, + IID_PPV_ARGS(&device)))) { + XELOGE("Failed to create a Direct3D 12 feature level 11_0 device."); + adapter->Release(); + dxgi_factory->Release(); + return false; + } + adapter->Release(); // Create the command queue for graphics. D3D12_COMMAND_QUEUE_DESC queue_desc; @@ -146,8 +147,14 @@ bool D3D12Provider::Initialize() { descriptor_size_dsv_ = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); - // Check if programmable sample positions are supported (added in Creators - // Update). + // Check if tiled resources and programmable sample positions (programmable + // sample positions added in Creators Update) are supported. + tiled_resources_tier_ = 0; + D3D12_FEATURE_DATA_D3D12_OPTIONS options; + if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, + &options, sizeof(options)))) { + tiled_resources_tier_ = uint32_t(options.TiledResourcesTier); + } programmable_sample_positions_tier_ = 0; D3D12_FEATURE_DATA_D3D12_OPTIONS2 options2; if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS2, @@ -155,25 +162,10 @@ bool D3D12Provider::Initialize() { programmable_sample_positions_tier_ = uint32_t(options2.ProgrammableSamplePositionsTier); } - XELOGD3D("Direct3D 12 device supports programmable sample positions tier %u", - programmable_sample_positions_tier_); - - return true; -} - -bool D3D12Provider::IsDeviceSupported(ID3D12Device* device) { - D3D12_FEATURE_DATA_D3D12_OPTIONS options; - if (FAILED(device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, - sizeof(options)))) { - return false; - } - - // Tiled resources required for shared memory emulation without excessive - // video memory usage. - if (FLAGS_d3d12_tiled_resources && - options.TiledResourcesTier < D3D12_TILED_RESOURCES_TIER_1) { - return false; - } + XELOGD3D( + "Direct3D 12 device supports tiled resources tier %u, programmable " + "sample positions tier %u", + tiled_resources_tier_, programmable_sample_positions_tier_); return true; } diff --git a/src/xenia/ui/d3d12/d3d12_provider.h b/src/xenia/ui/d3d12/d3d12_provider.h index 22c187795..d113c015a 100644 --- a/src/xenia/ui/d3d12/d3d12_provider.h +++ b/src/xenia/ui/d3d12/d3d12_provider.h @@ -58,6 +58,7 @@ class D3D12Provider : public GraphicsProvider { return start; } + uint32_t GetTiledResourcesTier() const { return tiled_resources_tier_; } uint32_t GetProgrammableSamplePositionsTier() const { return programmable_sample_positions_tier_; } @@ -66,7 +67,6 @@ class D3D12Provider : public GraphicsProvider { explicit D3D12Provider(Window* main_window); bool Initialize(); - static bool IsDeviceSupported(ID3D12Device* device); IDXGIFactory2* dxgi_factory_ = nullptr; ID3D12Device* device_ = nullptr; @@ -77,6 +77,7 @@ class D3D12Provider : public GraphicsProvider { uint32_t descriptor_size_rtv_; uint32_t descriptor_size_dsv_; + uint32_t tiled_resources_tier_; uint32_t programmable_sample_positions_tier_; };