Files
Xenia-Canary/src/xenia/ui/d3d12/cpu_fence.cc
2018-07-19 14:51:07 +03:00

76 lines
2.1 KiB
C++

/**
******************************************************************************
* 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/cpu_fence.h"
#include "xenia/base/logging.h"
namespace xe {
namespace ui {
namespace d3d12 {
std::unique_ptr<CPUFence>
CPUFence::Create(ID3D12Device* device, ID3D12CommandQueue* queue) {
std::unique_ptr<CPUFence> fence(new CPUFence(device, queue));
if (!fence->Initialize()) {
return nullptr;
}
return fence;
}
CPUFence::CPUFence(ID3D12Device* device, ID3D12CommandQueue* queue)
: device_(device), queue_(queue) {}
CPUFence::~CPUFence() {
// First destroying the fence because it may reference the event.
if (fence_ != nullptr) {
fence_->Release();
}
if (completion_event_ != nullptr) {
CloseHandle(completion_event_);
}
}
bool CPUFence::Initialize() {
if (FAILED(device_->CreateFence(0, D3D12_FENCE_FLAG_NONE,
IID_PPV_ARGS(&fence_)))) {
XELOGE("Failed to create a fence");
return false;
}
completion_event_ = CreateEvent(nullptr, false, false, nullptr);
if (completion_event_ == nullptr) {
XELOGE("Failed to create a fence completion event");
fence_->Release();
fence_ = nullptr;
return false;
}
queued_value_ = 0;
return true;
}
void CPUFence::Enqueue() {
++queued_value_;
queue_->Signal(fence_, queued_value_);
}
bool CPUFence::IsCompleted() {
return fence_->GetCompletedValue() >= queued_value_;
}
void CPUFence::Await() {
if (fence_->GetCompletedValue() < queued_value_) {
fence_->SetEventOnCompletion(queued_value_, completion_event_);
WaitForSingleObject(completion_event_, INFINITE);
}
}
} // namespace d3d12
} // namespace ui
} // namespace xe