From 2183a969af7e4bff715e13741315ea62655acc0b Mon Sep 17 00:00:00 2001 From: Triang3l Date: Mon, 30 Jul 2018 20:18:52 +0300 Subject: [PATCH] [D3D12] Make tiled resource toggleable, disable debug layer by default --- src/xenia/gpu/d3d12/d3d12_shader.cc | 2 +- src/xenia/gpu/d3d12/shared_memory.cc | 125 +++++++++++++++------------ src/xenia/ui/d3d12/d3d12_api.cc | 16 ++++ src/xenia/ui/d3d12/d3d12_api.h | 4 + src/xenia/ui/d3d12/d3d12_provider.cc | 13 ++- 5 files changed, 101 insertions(+), 59 deletions(-) create mode 100644 src/xenia/ui/d3d12/d3d12_api.cc diff --git a/src/xenia/gpu/d3d12/d3d12_shader.cc b/src/xenia/gpu/d3d12/d3d12_shader.cc index 8dc86bc1c..34238dc3a 100644 --- a/src/xenia/gpu/d3d12/d3d12_shader.cc +++ b/src/xenia/gpu/d3d12/d3d12_shader.cc @@ -15,7 +15,7 @@ #include "xenia/base/logging.h" #include "xenia/gpu/gpu_flags.h" -DEFINE_bool(d3d12_shader_disasm, true, +DEFINE_bool(d3d12_shader_disasm, false, "Disassemble translated shaders after compilation."); namespace xe { diff --git a/src/xenia/gpu/d3d12/shared_memory.cc b/src/xenia/gpu/d3d12/shared_memory.cc index 016d7dc23..33f6ebbb7 100644 --- a/src/xenia/gpu/d3d12/shared_memory.cc +++ b/src/xenia/gpu/d3d12/shared_memory.cc @@ -46,7 +46,7 @@ bool SharedMemory::Initialize() { buffer_state_ = D3D12_RESOURCE_STATE_COPY_DEST; D3D12_RESOURCE_DESC buffer_desc; buffer_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - buffer_desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; + buffer_desc.Alignment = 0; buffer_desc.Width = kBufferSize; buffer_desc.Height = 1; buffer_desc.DepthOrArraySize = 1; @@ -56,11 +56,23 @@ bool SharedMemory::Initialize() { buffer_desc.SampleDesc.Quality = 0; buffer_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; buffer_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - if (FAILED(device->CreateReservedResource(&buffer_desc, buffer_state_, - nullptr, IID_PPV_ARGS(&buffer_)))) { - XELOGE("Shared memory: Failed to create the 512 MB tiled buffer"); - Shutdown(); - return false; + if (FLAGS_d3d12_tiled_resources) { + if (FAILED(device->CreateReservedResource( + &buffer_desc, buffer_state_, nullptr, IID_PPV_ARGS(&buffer_)))) { + XELOGE("Shared memory: Failed to create the 512 MB tiled buffer"); + Shutdown(); + return false; + } + } else { + D3D12_HEAP_PROPERTIES heap_properties = {}; + heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT; + if (FAILED(device->CreateCommittedResource( + &heap_properties, D3D12_HEAP_FLAG_NONE, &buffer_desc, buffer_state_, + nullptr, IID_PPV_ARGS(&buffer_)))) { + XELOGE("Shared memory: Failed to create the 512 MB buffer"); + Shutdown(); + return false; + } } buffer_gpu_address_ = buffer_->GetGPUVirtualAddress(); @@ -95,10 +107,12 @@ void SharedMemory::Shutdown() { buffer_ = nullptr; } - for (uint32_t i = 0; i < xe::countof(heaps_); ++i) { - if (heaps_[i] != nullptr) { - heaps_[i]->Release(); - heaps_[i] = nullptr; + if (FLAGS_d3d12_tiled_resources) { + for (uint32_t i = 0; i < xe::countof(heaps_); ++i) { + if (heaps_[i] != nullptr) { + heaps_[i]->Release(); + heaps_[i] = nullptr; + } } } } @@ -276,52 +290,53 @@ bool SharedMemory::UseRange(uint32_t start, uint32_t length) { // XELOGGPU("Shared memory: Range %.8X-%.8X is being used", start, last); // Ensure all tile heaps are present. - uint32_t heap_first = start >> kHeapSizeLog2; - uint32_t heap_last = last >> kHeapSizeLog2; - for (uint32_t i = heap_first; i <= heap_last; ++i) { - if (heaps_[i] != nullptr) { - continue; + if (FLAGS_d3d12_tiled_resources) { + uint32_t heap_first = start >> kHeapSizeLog2; + uint32_t heap_last = last >> kHeapSizeLog2; + for (uint32_t i = heap_first; i <= heap_last; ++i) { + if (heaps_[i] != nullptr) { + continue; + } + if (heap_creation_failed_) { + // Don't try to create a heap for every vertex buffer or texture in the + // current frame anymore if have failed at least once. + return false; + } + /* XELOGGPU("Shared memory: Creating %.8X-%.8X tile heap", + heap_first << kHeapSizeLog2, + (heap_last << kHeapSizeLog2) + (kHeapSize - 1)); */ + auto provider = context_->GetD3D12Provider(); + auto device = provider->GetDevice(); + auto direct_queue = provider->GetDirectQueue(); + D3D12_HEAP_DESC heap_desc = {}; + heap_desc.SizeInBytes = kHeapSize; + heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; + heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS; + if (FAILED(device->CreateHeap(&heap_desc, IID_PPV_ARGS(&heaps_[i])))) { + XELOGE("Shared memory: Failed to create a tile heap"); + heap_creation_failed_ = true; + return false; + } + D3D12_TILED_RESOURCE_COORDINATE region_start_coordinates; + region_start_coordinates.X = i << (kHeapSizeLog2 - kTileSizeLog2); + region_start_coordinates.Y = 0; + region_start_coordinates.Z = 0; + region_start_coordinates.Subresource = 0; + D3D12_TILE_REGION_SIZE region_size; + region_size.NumTiles = kHeapSize >> kTileSizeLog2; + region_size.UseBox = FALSE; + D3D12_TILE_RANGE_FLAGS range_flags = D3D12_TILE_RANGE_FLAG_NONE; + UINT heap_range_start_offset = 0; + UINT range_tile_count = kHeapSize >> kTileSizeLog2; + // FIXME(Triang3l): This may cause issues if the emulator is shut down + // mid-frame and the heaps are destroyed before tile mappings are updated + // (AwaitAllFramesCompletion won't catch this then). Defer this until the + // actual command list submission at the end of the frame. + direct_queue->UpdateTileMappings( + buffer_, 1, ®ion_start_coordinates, ®ion_size, heaps_[i], 1, + &range_flags, &heap_range_start_offset, &range_tile_count, + D3D12_TILE_MAPPING_FLAG_NONE); } - if (heap_creation_failed_) { - // Don't try to create a heap for every vertex buffer or texture in the - // current frame anymore if have failed at least once. - return false; - } - /* XELOGGPU("Shared memory: Creating %.8X-%.8X tile heap", - heap_first << kHeapSizeLog2, - (heap_last << kHeapSizeLog2) + (kHeapSize - 1)); */ - auto provider = context_->GetD3D12Provider(); - auto device = provider->GetDevice(); - auto direct_queue = provider->GetDirectQueue(); - D3D12_HEAP_DESC heap_desc = {}; - heap_desc.SizeInBytes = kHeapSize; - heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; - // Flags are required on resource heap tier 1! - heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS; - if (FAILED(device->CreateHeap(&heap_desc, IID_PPV_ARGS(&heaps_[i])))) { - XELOGE("Shared memory: Failed to create a tile heap"); - heap_creation_failed_ = true; - return false; - } - D3D12_TILED_RESOURCE_COORDINATE region_start_coordinates; - region_start_coordinates.X = i << (kHeapSizeLog2 - kTileSizeLog2); - region_start_coordinates.Y = 0; - region_start_coordinates.Z = 0; - region_start_coordinates.Subresource = 0; - D3D12_TILE_REGION_SIZE region_size; - region_size.NumTiles = kHeapSize >> kTileSizeLog2; - region_size.UseBox = FALSE; - D3D12_TILE_RANGE_FLAGS range_flags = D3D12_TILE_RANGE_FLAG_NONE; - UINT heap_range_start_offset = 0; - UINT range_tile_count = kHeapSize >> kTileSizeLog2; - // FIXME(Triang3l): This may cause issues if the emulator is shut down - // mid-frame and the heaps are destroyed before tile mappings are updated - // (AwaitAllFramesCompletion won't catch this then). Defer this until the - // actual command list submission at the end of the frame. - direct_queue->UpdateTileMappings( - buffer_, 1, ®ion_start_coordinates, ®ion_size, heaps_[i], 1, - &range_flags, &heap_range_start_offset, &range_tile_count, - D3D12_TILE_MAPPING_FLAG_NONE); } // Mark the outdated tiles in this range as requiring upload, and also make diff --git a/src/xenia/ui/d3d12/d3d12_api.cc b/src/xenia/ui/d3d12/d3d12_api.cc new file mode 100644 index 000000000..142701520 --- /dev/null +++ b/src/xenia/ui/d3d12/d3d12_api.cc @@ -0,0 +1,16 @@ +/** + ****************************************************************************** + * 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 b3528a3f9..e1d3149d5 100644 --- a/src/xenia/ui/d3d12/d3d12_api.h +++ b/src/xenia/ui/d3d12/d3d12_api.h @@ -10,6 +10,8 @@ #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" @@ -19,4 +21,6 @@ #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 cafd12b6a..fbed99826 100644 --- a/src/xenia/ui/d3d12/d3d12_provider.cc +++ b/src/xenia/ui/d3d12/d3d12_provider.cc @@ -14,7 +14,7 @@ #include "xenia/base/logging.h" #include "xenia/ui/d3d12/d3d12_context.h" -DEFINE_bool(d3d12_debug, true, "Enable Direct3D 12 and DXGI debug layer."); +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. " "-1 for any physical adapter, -2 for WARP software rendering."); @@ -155,8 +155,15 @@ bool D3D12Provider::IsDeviceSupported(ID3D12Device* device) { sizeof(options)))) { return false; } - // Tiled resources required for virtual memory. - return options.TiledResourcesTier >= D3D12_TILED_RESOURCES_TIER_1; + + // 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; + } + + return true; } std::unique_ptr D3D12Provider::CreateContext(