From f5e91ba97ca168f815414548c35e700545966b25 Mon Sep 17 00:00:00 2001 From: Triang3l Date: Thu, 19 Jul 2018 14:51:07 +0300 Subject: [PATCH] [D3D12] Command list, fence cleanup --- src/xenia/ui/d3d12/command_list.cc | 79 ++++++++++++++++++++++++++++++ src/xenia/ui/d3d12/command_list.h | 52 ++++++++++++++++++++ src/xenia/ui/d3d12/cpu_fence.cc | 2 +- src/xenia/ui/d3d12/cpu_fence.h | 2 +- 4 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 src/xenia/ui/d3d12/command_list.cc create mode 100644 src/xenia/ui/d3d12/command_list.h diff --git a/src/xenia/ui/d3d12/command_list.cc b/src/xenia/ui/d3d12/command_list.cc new file mode 100644 index 000000000..f79600826 --- /dev/null +++ b/src/xenia/ui/d3d12/command_list.cc @@ -0,0 +1,79 @@ +/** + ****************************************************************************** + * 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/command_list.h" + +#include "xenia/base/logging.h" + +namespace xe { +namespace ui { +namespace d3d12 { + +std::unique_ptr +CommandList::Create(ID3D12Device* device, ID3D12CommandQueue* queue, + D3D12_COMMAND_LIST_TYPE type) { + std::unique_ptr command_list(new CommandList(device, queue, + type)); + if (!command_list->Initialize()) { + return nullptr; + } + return command_list; +} + +CommandList::CommandList(ID3D12Device* device, ID3D12CommandQueue* queue, + D3D12_COMMAND_LIST_TYPE type) + : device_(device), queue_(queue), type_(type) {} + +CommandList::~CommandList() { + if (command_list_ != nullptr) { + command_list_->Release(); + } + if (command_allocator_ != nullptr) { + command_allocator_->Release(); + } +} + +bool CommandList::Initialize() { + if (FAILED(device_->CreateCommandAllocator( + type_, IID_PPV_ARGS(&command_allocator_)))) { + XELOGE("Failed to create a command allocator"); + return false; + } + if (FAILED(device_->CreateCommandList(0, type_, command_allocator_, nullptr, + IID_PPV_ARGS(&command_list_)))) { + XELOGE("Failed to create a graphics command list"); + command_allocator_->Release(); + command_allocator_ = nullptr; + return false; + } + // A command list is initially open, need to close it before resetting. + command_list_->Close(); + return true; +} + +ID3D12GraphicsCommandList* CommandList::BeginRecording() { + command_allocator_->Reset(); + command_list_->Reset(command_allocator_, nullptr); + return command_list_; +} + +void CommandList::AbortRecording() { + command_list_->Close(); +} + +void CommandList::Execute() { + command_list_->Close(); + ID3D12CommandList* execute_lists[] = { command_list_ }; + queue_->ExecuteCommandLists(1, execute_lists); +} + +} // namespace d3d12 +} // namespace ui +} // namespace xe + diff --git a/src/xenia/ui/d3d12/command_list.h b/src/xenia/ui/d3d12/command_list.h new file mode 100644 index 000000000..10ac0d24b --- /dev/null +++ b/src/xenia/ui/d3d12/command_list.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * 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. * + ****************************************************************************** + */ + +#ifndef XENIA_UI_D3D12_COMMAND_LIST_H_ +#define XENIA_UI_D3D12_COMMAND_LIST_H_ + +#include + +#include "xenia/ui/d3d12/d3d12_api.h" + +namespace xe { +namespace ui { +namespace d3d12 { + +class CommandList { + public: + ~CommandList(); + + static std::unique_ptr Create(ID3D12Device* device, + ID3D12CommandQueue* queue, + D3D12_COMMAND_LIST_TYPE type); + + ID3D12GraphicsCommandList* GetCommandList() const { return command_list_; } + + ID3D12GraphicsCommandList* BeginRecording(); + void AbortRecording(); + void Execute(); + + protected: + CommandList(ID3D12Device* device, ID3D12CommandQueue* queue, + D3D12_COMMAND_LIST_TYPE type); + bool Initialize(); + + ID3D12Device* device_; + ID3D12CommandQueue* queue_; + D3D12_COMMAND_LIST_TYPE type_; + + ID3D12CommandAllocator* command_allocator_ = nullptr; + ID3D12GraphicsCommandList* command_list_ = nullptr; +}; + +} // namespace d3d12 +} // namespace ui +} // namespace xe + +#endif // XENIA_UI_D3D12_CPU_FENCE_H_ diff --git a/src/xenia/ui/d3d12/cpu_fence.cc b/src/xenia/ui/d3d12/cpu_fence.cc index e01363915..9f7ff3a5c 100644 --- a/src/xenia/ui/d3d12/cpu_fence.cc +++ b/src/xenia/ui/d3d12/cpu_fence.cc @@ -40,7 +40,7 @@ CPUFence::~CPUFence() { bool CPUFence::Initialize() { if (FAILED(device_->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence_)))) { - XELOGE("Failed to create a Direct3D fence"); + XELOGE("Failed to create a fence"); return false; } completion_event_ = CreateEvent(nullptr, false, false, nullptr); diff --git a/src/xenia/ui/d3d12/cpu_fence.h b/src/xenia/ui/d3d12/cpu_fence.h index 4f77dee65..647eb5c47 100644 --- a/src/xenia/ui/d3d12/cpu_fence.h +++ b/src/xenia/ui/d3d12/cpu_fence.h @@ -34,7 +34,7 @@ class CPUFence { void Await(); private: - CPUFence::CPUFence(ID3D12Device* device, ID3D12CommandQueue* queue); + CPUFence(ID3D12Device* device, ID3D12CommandQueue* queue); bool Initialize(); ID3D12Device* device_;