[D3D12] Make tiled resources optional - not available on old Intel HD Graphics
This commit is contained in:
parent
9e17bbf016
commit
90f586383a
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#include "xenia/gpu/d3d12/shared_memory.h"
|
#include "xenia/gpu/d3d12/shared_memory.h"
|
||||||
|
|
||||||
|
#include <gflags/gflags.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
@ -20,6 +22,12 @@
|
||||||
#include "xenia/gpu/d3d12/d3d12_command_processor.h"
|
#include "xenia/gpu/d3d12/d3d12_command_processor.h"
|
||||||
#include "xenia/ui/d3d12/d3d12_util.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 xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
|
@ -45,7 +53,7 @@ bool SharedMemory::Initialize() {
|
||||||
ui::d3d12::util::FillBufferResourceDesc(
|
ui::d3d12::util::FillBufferResourceDesc(
|
||||||
buffer_desc, kBufferSize, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
|
buffer_desc, kBufferSize, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
|
||||||
buffer_state_ = D3D12_RESOURCE_STATE_COPY_DEST;
|
buffer_state_ = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||||
if (FLAGS_d3d12_tiled_resources) {
|
if (AreTiledResourcesUsed()) {
|
||||||
if (FAILED(device->CreateReservedResource(
|
if (FAILED(device->CreateReservedResource(
|
||||||
&buffer_desc, buffer_state_, nullptr, IID_PPV_ARGS(&buffer_)))) {
|
&buffer_desc, buffer_state_, nullptr, IID_PPV_ARGS(&buffer_)))) {
|
||||||
XELOGE("Shared memory: Failed to create the 512 MB tiled buffer");
|
XELOGE("Shared memory: Failed to create the 512 MB tiled buffer");
|
||||||
|
@ -53,6 +61,10 @@ bool SharedMemory::Initialize() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} 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(
|
if (FAILED(device->CreateCommittedResource(
|
||||||
&ui::d3d12::util::kHeapPropertiesDefault, D3D12_HEAP_FLAG_NONE,
|
&ui::d3d12::util::kHeapPropertiesDefault, D3D12_HEAP_FLAG_NONE,
|
||||||
&buffer_desc, buffer_state_, nullptr, IID_PPV_ARGS(&buffer_)))) {
|
&buffer_desc, buffer_state_, nullptr, IID_PPV_ARGS(&buffer_)))) {
|
||||||
|
@ -91,7 +103,7 @@ void SharedMemory::Shutdown() {
|
||||||
buffer_ = nullptr;
|
buffer_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_d3d12_tiled_resources) {
|
if (AreTiledResourcesUsed()) {
|
||||||
for (uint32_t i = 0; i < xe::countof(heaps_); ++i) {
|
for (uint32_t i = 0; i < xe::countof(heaps_); ++i) {
|
||||||
if (heaps_[i] != nullptr) {
|
if (heaps_[i] != nullptr) {
|
||||||
heaps_[i]->Release();
|
heaps_[i]->Release();
|
||||||
|
@ -197,7 +209,7 @@ bool SharedMemory::MakeTilesResident(uint32_t start, uint32_t length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FLAGS_d3d12_tiled_resources) {
|
if (!AreTiledResourcesUsed()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,6 +365,14 @@ void SharedMemory::RangeWrittenByGPU(uint32_t start, uint32_t length) {
|
||||||
MakeRangeValid(page_first, page_last - page_first + 1);
|
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,
|
void SharedMemory::MakeRangeValid(uint32_t valid_page_first,
|
||||||
uint32_t valid_page_count) {
|
uint32_t valid_page_count) {
|
||||||
if (valid_page_first >= page_count_ || valid_page_count == 0) {
|
if (valid_page_first >= page_count_ || valid_page_count == 0) {
|
||||||
|
|
|
@ -93,6 +93,8 @@ class SharedMemory {
|
||||||
void CreateRawUAV(D3D12_CPU_DESCRIPTOR_HANDLE handle);
|
void CreateRawUAV(D3D12_CPU_DESCRIPTOR_HANDLE handle);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool AreTiledResourcesUsed() const;
|
||||||
|
|
||||||
// Mark the memory range as updated and protect it. The validity mutex must
|
// Mark the memory range as updated and protect it. The validity mutex must
|
||||||
// NOT be held when calling!!!
|
// NOT be held when calling!!!
|
||||||
void MakeRangeValid(uint32_t valid_page_first, uint32_t valid_page_count);
|
void MakeRangeValid(uint32_t valid_page_first, uint32_t valid_page_count);
|
||||||
|
|
|
@ -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.");
|
|
|
@ -10,8 +10,6 @@
|
||||||
#ifndef XENIA_UI_D3D12_D3D12_API_H_
|
#ifndef XENIA_UI_D3D12_D3D12_API_H_
|
||||||
#define XENIA_UI_D3D12_D3D12_API_H_
|
#define XENIA_UI_D3D12_D3D12_API_H_
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
// This must be included before D3D and DXGI for things like NOMINMAX.
|
// This must be included before D3D and DXGI for things like NOMINMAX.
|
||||||
#include "xenia/base/platform_win.h"
|
#include "xenia/base/platform_win.h"
|
||||||
|
|
||||||
|
@ -21,6 +19,4 @@
|
||||||
|
|
||||||
#define XELOGD3D XELOGI
|
#define XELOGD3D XELOGI
|
||||||
|
|
||||||
DECLARE_bool(d3d12_tiled_resources);
|
|
||||||
|
|
||||||
#endif // XENIA_UI_D3D12_D3D12_API_H_
|
#endif // XENIA_UI_D3D12_D3D12_API_H_
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
#include "xenia/ui/d3d12/d3d12_context.h"
|
#include "xenia/ui/d3d12/d3d12_context.h"
|
||||||
|
|
||||||
DEFINE_bool(d3d12_debug, false, "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. "
|
DEFINE_int32(d3d12_adapter_index, -1,
|
||||||
|
"Index of the DXGI adapter to use. "
|
||||||
"-1 for any physical adapter, -2 for WARP software rendering.");
|
"-1 for any physical adapter, -2 for WARP software rendering.");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
@ -29,7 +30,7 @@ std::unique_ptr<D3D12Provider> D3D12Provider::Create(Window* main_window) {
|
||||||
"Unable to initialize Direct3D 12 graphics subsystem.\n"
|
"Unable to initialize Direct3D 12 graphics subsystem.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Ensure that you have the latest drivers for your GPU and it supports "
|
"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"
|
"\n"
|
||||||
"See http://xenia.jp/faq/ for more information and a list of supported "
|
"See http://xenia.jp/faq/ for more information and a list of supported "
|
||||||
"GPUs.");
|
"GPUs.");
|
||||||
|
@ -79,44 +80,44 @@ bool D3D12Provider::Initialize() {
|
||||||
// TODO(Triang3l): Log adapter info (contains a wide string).
|
// TODO(Triang3l): Log adapter info (contains a wide string).
|
||||||
uint32_t adapter_index = 0;
|
uint32_t adapter_index = 0;
|
||||||
IDXGIAdapter1* adapter = nullptr;
|
IDXGIAdapter1* adapter = nullptr;
|
||||||
ID3D12Device* device = nullptr;
|
|
||||||
while (dxgi_factory->EnumAdapters1(adapter_index, &adapter) == S_OK) {
|
while (dxgi_factory->EnumAdapters1(adapter_index, &adapter) == S_OK) {
|
||||||
DXGI_ADAPTER_DESC1 adapter_desc;
|
DXGI_ADAPTER_DESC1 adapter_desc;
|
||||||
if (SUCCEEDED(adapter->GetDesc1(&adapter_desc))) {
|
if (SUCCEEDED(adapter->GetDesc1(&adapter_desc))) {
|
||||||
if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0,
|
if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0,
|
||||||
IID_PPV_ARGS(&device)))) {
|
_uuidof(ID3D12Device), nullptr))) {
|
||||||
if (IsDeviceSupported(device)) {
|
if (FLAGS_d3d12_adapter_index >= 0) {
|
||||||
if (FLAGS_d3d12_adapter_index >= 0) {
|
if (adapter_index == FLAGS_d3d12_adapter_index) {
|
||||||
if (adapter_index == FLAGS_d3d12_adapter_index) {
|
break;
|
||||||
break;
|
}
|
||||||
}
|
} else if (FLAGS_d3d12_adapter_index == -2) {
|
||||||
} else if (FLAGS_d3d12_adapter_index == -2) {
|
if (adapter_desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
|
||||||
if (adapter_desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
|
break;
|
||||||
break;
|
}
|
||||||
}
|
} else {
|
||||||
} else {
|
if (!(adapter_desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)) {
|
||||||
if (!(adapter_desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)) {
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
device->Release();
|
|
||||||
device = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
adapter->Release();
|
adapter->Release();
|
||||||
adapter = nullptr;
|
adapter = nullptr;
|
||||||
++adapter_index;
|
++adapter_index;
|
||||||
}
|
}
|
||||||
if (adapter != nullptr) {
|
if (adapter == nullptr) {
|
||||||
adapter->Release();
|
XELOGE("Failed to get an adapter supporting Direct3D feature level 11_0.");
|
||||||
}
|
|
||||||
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.");
|
|
||||||
dxgi_factory->Release();
|
dxgi_factory->Release();
|
||||||
return false;
|
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.
|
// Create the command queue for graphics.
|
||||||
D3D12_COMMAND_QUEUE_DESC queue_desc;
|
D3D12_COMMAND_QUEUE_DESC queue_desc;
|
||||||
|
@ -146,8 +147,14 @@ bool D3D12Provider::Initialize() {
|
||||||
descriptor_size_dsv_ =
|
descriptor_size_dsv_ =
|
||||||
device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
|
device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
|
||||||
|
|
||||||
// Check if programmable sample positions are supported (added in Creators
|
// Check if tiled resources and programmable sample positions (programmable
|
||||||
// Update).
|
// 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;
|
programmable_sample_positions_tier_ = 0;
|
||||||
D3D12_FEATURE_DATA_D3D12_OPTIONS2 options2;
|
D3D12_FEATURE_DATA_D3D12_OPTIONS2 options2;
|
||||||
if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS2,
|
if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS2,
|
||||||
|
@ -155,25 +162,10 @@ bool D3D12Provider::Initialize() {
|
||||||
programmable_sample_positions_tier_ =
|
programmable_sample_positions_tier_ =
|
||||||
uint32_t(options2.ProgrammableSamplePositionsTier);
|
uint32_t(options2.ProgrammableSamplePositionsTier);
|
||||||
}
|
}
|
||||||
XELOGD3D("Direct3D 12 device supports programmable sample positions tier %u",
|
XELOGD3D(
|
||||||
programmable_sample_positions_tier_);
|
"Direct3D 12 device supports tiled resources tier %u, programmable "
|
||||||
|
"sample positions tier %u",
|
||||||
return true;
|
tiled_resources_tier_, programmable_sample_positions_tier_);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ class D3D12Provider : public GraphicsProvider {
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t GetTiledResourcesTier() const { return tiled_resources_tier_; }
|
||||||
uint32_t GetProgrammableSamplePositionsTier() const {
|
uint32_t GetProgrammableSamplePositionsTier() const {
|
||||||
return programmable_sample_positions_tier_;
|
return programmable_sample_positions_tier_;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +67,6 @@ class D3D12Provider : public GraphicsProvider {
|
||||||
explicit D3D12Provider(Window* main_window);
|
explicit D3D12Provider(Window* main_window);
|
||||||
|
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
static bool IsDeviceSupported(ID3D12Device* device);
|
|
||||||
|
|
||||||
IDXGIFactory2* dxgi_factory_ = nullptr;
|
IDXGIFactory2* dxgi_factory_ = nullptr;
|
||||||
ID3D12Device* device_ = nullptr;
|
ID3D12Device* device_ = nullptr;
|
||||||
|
@ -77,6 +77,7 @@ class D3D12Provider : public GraphicsProvider {
|
||||||
uint32_t descriptor_size_rtv_;
|
uint32_t descriptor_size_rtv_;
|
||||||
uint32_t descriptor_size_dsv_;
|
uint32_t descriptor_size_dsv_;
|
||||||
|
|
||||||
|
uint32_t tiled_resources_tier_;
|
||||||
uint32_t programmable_sample_positions_tier_;
|
uint32_t programmable_sample_positions_tier_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue