Bicameral Engine
GPU-resident engine for a magic-research open-world game
Loading...
Searching...
No Matches
swap_chain.h
Go to the documentation of this file.
1// swap_chain.h — 窓に描くためのスワップチェイン(T-0004、docs/design/06-simulation-loop.md §4)。
2//
3// フリップモデル(FLIP_DISCARD)で BUFFER_COUNT 枚。FRAME_LATENCY_WAITABLE_OBJECT を使い、CPU は WaitForFrame() で
4// 「次のフレームを描き始めてよい」まで待つ(これがフレームの歩調。GPU のフェンスを CPU が待つのではない)。
5// 先に進めるフレームの数は SetMaximumFrameLatency で決める(maxFrameLatency。2〜3。T-0004 の完了条件)。
6// vsync なしで tearing に対応していれば、ALLOW_TEARING で Present する(可変リフレッシュの画面向け)。
7#pragma once
8
9#include <array>
10#include <cstdint>
11#include <expected>
12#include <memory>
13#include <string>
14
15#include "gpu/com_ptr.h"
16
17namespace bicameral::gpu {
18
19 class SwapChain {
20 public:
21 static constexpr uint32_t BUFFER_COUNT = 3;
22 static constexpr DXGI_FORMAT FORMAT = DXGI_FORMAT_R8G8B8A8_UNORM;
23
24 [[nodiscard]] static std::expected<SwapChain, std::string> Create(ID3D12Device* device, IDXGIFactory6* factory,
25 ID3D12CommandQueue* directQueue, HWND window,
26 uint32_t maxFrameLatency);
27
28 // 次のフレームを始めてよいまで待つ(最大 timeoutMs)。待ちきれなければ false(そのフレームも進めてよい)
29 bool WaitForFrame(uint32_t timeoutMs) const;
30
31 [[nodiscard]] uint32_t CurrentIndex() const { return m_swapChain->GetCurrentBackBufferIndex(); }
32 [[nodiscard]] ID3D12Resource* BackBuffer(uint32_t index) const { return m_buffers[index].Get(); }
33 [[nodiscard]] D3D12_CPU_DESCRIPTOR_HANDLE RenderTargetView(uint32_t index) const;
34 [[nodiscard]] uint32_t Width() const { return m_width; }
35 [[nodiscard]] uint32_t Height() const { return m_height; }
36
37 // 失敗(デバイスの喪失など)なら false
38 bool Present(bool vsync) const;
39
40 // 窓の大きさに合わせる。呼ぶ側の約束: バックバッファを使うコマンドを GPU が全部終えている(記録済みのリストも作り直す)
41 bool Resize(ID3D12Device* device, uint32_t width, uint32_t height);
42
43 private:
44 SwapChain() = default;
45
46 bool AcquireBuffers(ID3D12Device* device);
47
48 struct HandleCloser {
49 void operator()(HANDLE handle) const { CloseHandle(handle); }
50 };
51
52 // --- バックバッファ ---
53 ComPtr<IDXGISwapChain3> m_swapChain;
54 ComPtr<ID3D12DescriptorHeap> m_rtvHeap;
55 std::array<ComPtr<ID3D12Resource>, BUFFER_COUNT> m_buffers;
56 uint32_t m_rtvStride = 0;
57
58 // 使い終わったら閉じる(GetFrameLatencyWaitableObject)
59 std::unique_ptr<void, HandleCloser> m_frameLatencyWaitable;
60
61 // --- 大きさと機能 ---
62 uint32_t m_width = 0;
63 uint32_t m_height = 0;
64 bool m_tearingSupported = false;
65 };
66
67} // namespace bicameral::gpu
bool AcquireBuffers(ID3D12Device *device)
bool Present(bool vsync) const
static constexpr DXGI_FORMAT FORMAT
Definition swap_chain.h:22
ID3D12Resource * BackBuffer(uint32_t index) const
Definition swap_chain.h:32
uint32_t CurrentIndex() const
Definition swap_chain.h:31
std::array< ComPtr< ID3D12Resource >, BUFFER_COUNT > m_buffers
Definition swap_chain.h:55
std::unique_ptr< void, HandleCloser > m_frameLatencyWaitable
Definition swap_chain.h:59
ComPtr< ID3D12DescriptorHeap > m_rtvHeap
Definition swap_chain.h:54
static constexpr uint32_t BUFFER_COUNT
Definition swap_chain.h:21
bool WaitForFrame(uint32_t timeoutMs) const
D3D12_CPU_DESCRIPTOR_HANDLE RenderTargetView(uint32_t index) const
ComPtr< IDXGISwapChain3 > m_swapChain
Definition swap_chain.h:53
bool Resize(ID3D12Device *device, uint32_t width, uint32_t height)
uint32_t Width() const
Definition swap_chain.h:34
uint32_t Height() const
Definition swap_chain.h:35
static std::expected< SwapChain, std::string > Create(ID3D12Device *device, IDXGIFactory6 *factory, ID3D12CommandQueue *directQueue, HWND window, uint32_t maxFrameLatency)
void operator()(HANDLE handle) const
Definition swap_chain.h:49