Bicameral Engine
GPU-resident engine for a magic-research open-world game
Loading...
Searching...
No Matches
queue.cpp
Go to the documentation of this file.
1// queue.cpp — コマンドキューとフェンス(T-0004)。使い方は queue.h。
2#include "gpu/queue.h"
3
4#include "core/hresult.h"
5#include "core/log.h"
6#include "gpu/com_ptr.h"
7
8namespace bicameral::gpu {
9
10 std::expected<Queue, std::string> Queue::Create(ID3D12Device* device, D3D12_COMMAND_LIST_TYPE type,
11 std::wstring_view name, D3D12_COMMAND_QUEUE_PRIORITY priority) {
12 Queue queue;
13 const D3D12_COMMAND_QUEUE_DESC desc{.Type = type, .Priority = priority};
14 HRESULT result = device->CreateCommandQueue(&desc, IID_PPV_ARGS(&queue.m_queue));
15 if (FAILED(result))
16 return std::unexpected("コマンドキューを作れない: " + DescribeHresult(result));
17
18 result = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&queue.m_fence));
19 if (FAILED(result))
20 return std::unexpected("フェンスを作れない: " + DescribeHresult(result));
21
22 queue.m_queue->SetName(std::wstring(name).c_str());
23 queue.m_fence->SetName((std::wstring(name) + L".fence").c_str());
24
25 return queue;
26 }
27
28 uint64_t Queue::Submit(std::span<ID3D12CommandList* const> lists) {
29 if (!lists.empty())
30 m_queue->ExecuteCommandLists(static_cast<UINT>(lists.size()), lists.data());
31
34
35 return m_lastSubmitted;
36 }
37
38 void Queue::Execute(ID3D12CommandList* list) const {
39 m_queue->ExecuteCommandLists(1, &list);
40 }
41
42 void Queue::GpuWait(const Queue& other, uint64_t value) const {
43 if (value == 0)
44 return;
45
46 (void)BICAMERAL_CHECK_HR(Channel::Gpu, m_queue->Wait(other.m_fence.Get(), value));
47 }
48
49 bool Queue::WaitCpu(uint64_t value) const {
50 if (IsDeviceLost())
51 return false;
52
53 if (IsComplete(value))
54 return true;
55
56 // イベントに nullptr を渡すと、終わるまでこの呼び出しの中で待つ
57 if (!BICAMERAL_CHECK_HR(Channel::Gpu, m_fence->SetEventOnCompletion(value, nullptr)))
58 return false;
59
60 return !IsDeviceLost();
61 }
62
63 uint64_t Queue::TimestampFrequency() const {
64 uint64_t frequency = 0;
65 if (FAILED(m_queue->GetTimestampFrequency(&frequency)))
66 return 0;
67
68 return frequency;
69 }
70
71} // namespace bicameral::gpu
bool WaitCpu(uint64_t value) const
Definition queue.cpp:49
ComPtr< ID3D12CommandQueue > m_queue
Definition queue.h:62
uint64_t TimestampFrequency() const
Definition queue.cpp:63
bool IsComplete(uint64_t value) const
Definition queue.h:43
static std::expected< Queue, std::string > Create(ID3D12Device *device, D3D12_COMMAND_LIST_TYPE type, std::wstring_view name, D3D12_COMMAND_QUEUE_PRIORITY priority=D3D12_COMMAND_QUEUE_PRIORITY_NORMAL)
Definition queue.cpp:10
void Execute(ID3D12CommandList *list) const
Definition queue.cpp:38
void GpuWait(const Queue &other, uint64_t value) const
Definition queue.cpp:42
uint64_t Submit(std::span< ID3D12CommandList *const > lists)
Definition queue.cpp:28
ComPtr< ID3D12Fence > m_fence
Definition queue.h:63
bool IsDeviceLost() const
Definition queue.h:46
uint64_t m_lastSubmitted
Definition queue.h:64
#define BICAMERAL_CHECK_HR(channel, expression)
Definition hresult.h:32
std::string DescribeHresult(HResult result)
Definition hresult.cpp:88