Bicameral Engine
GPU-resident engine for a magic-research open-world game
Loading...
Searching...
No Matches
gpu_multires.h
Go to the documentation of this file.
1// gpu_multires.h — 多重解像度の木(sim/multires_nest の CPU リファレンスと同じ形)を GPU に置き、
2// 世界の木の要求の処理(Compute の段 shaders/sim/multires_tree.hlsl + Work Graph shaders/sim/multires_graph.hlsl。T-0018)・
3// 観察の影を作る・引き戻す(Work Graph の再帰)・反応の刻み(Compute。multires_step.hlsl)を記録する(T-0017)。
4// 活性のブロックだけ刻む(Work Graph の ActivitySeedNode → WakeFaceNode → ActivityStepNode。T-0100)と、
5// 静かな葉を粗くする要求を作る(Compute の TreeQuiet。T-0101)・静かで一様になった頁を畳む(TreeFoldCheck → TreeFold。T-0103)もできる。
6// 活性の種の一覧は 2 本を刻みごとに入れ替える(この刻みの種 = GPU の入力、次の刻みの種 = u13 に書き足す)。
7// 熱の伝導(MultiresStepOptions::conduction。T-0107)は Compute の段 shaders/sim/multires_conduct.hlsl(印 → 頁 → 端数の枠 → 埋める →
8// 面の流れ → 変化を足して反応)。活性の刻みでは Work Graph が刻むブロックを伝導の一覧に足し、段はその一覧のブロックだけを受け持つ。
9// 細かいレベルの小刻み(subcycleBaseLevel・maxSubcycleGap。T-0109)は、印 〜 流れを小刻みごとに積み、小刻みの終わりに変化を足して
10// (ConductEnd)変わったブロックの隣を活性のグラフで起こす。
11// 細かいレベルの熱の陰解法(MultiresStepOptions::implicitConduction。T-0132)は、流れの段が基準より細かいブロックを飛ばし、流れの後に
12// 陰解法の段(sim/gpu_multires_implicit。EnableImplicitConduction で作る)が系を作って解き、変化を伝導の表へ足す(ConductApply が足す)。
13//
14// 使い方(テスト。1 刻み = 要求の処理と影の出来事 → 刻む → 影の引き戻し。CPU の test::StepMultiresScene と同じ順。
15// 刻むのは RecordStep〔全部〕か RecordStepActive〔活性だけ。CPU の StepActive〕):
16// auto gpu = GpuMultires::Create(device, table, capacity);
17// gpu->RecordUpload(list, nest); // 最初だけ
18// gpu->RecordRequests(list, requests); gpu->RecordProcessRequests(list, ring);
19// gpu->RecordStep(list, ring, seed, tick); gpu->RecordPullBack(list, ring, ...);
20// gpu->RecordReadback(list); → 投げて待つ → gpu->Read(nest);
21// 各操作の後に UAV のバリアを入れる(次の操作は前の書き込みを読む)。
22// 覗き窓(sim/probe_peek。T-0096)は、同じルート署名で自分の Compute(世界の写し・抽出)を起動する: SetExternalViews で u4・u5 に
23// 外のバッファを結び、RecordExternalDispatch で外の定数 4 語つきで投げる。
24#pragma once
25
26#include <array>
27#include <cstdint>
28#include <expected>
29#include <memory>
30#include <optional>
31#include <span>
32#include <string>
33#include <vector>
34
35#include "gpu/com_ptr.h"
36#include "gpu/work_graph.h"
37#include "sim/multires_nest.h"
38#include "sim/reaction_table.h"
39
40namespace bicameral::sim {
41
43 // 活性の Work Graph(shaders/sim/multires_activity_graph.hlsl)を作る。RecordStepActive に要る。
44 // 反応の核を含んで大きい(debug の GPU-based validation で作るのに数分)ので、使う時だけ
45 bool activity = false;
46
47 // 活性の刻みの熱の伝導の段(埋める・流れ・足す)を Work Graph(shaders/sim/multires_conduct_graph.hlsl)で投げる。
48 // 無ければ Compute(全部の枠の数だけグループを投げ、一覧の数を超えたグループは何もしない)。T-0107 で両方を測り、差は揺れの中で
49 // Compute がわずかに安かったので既定は Compute(D-302。docs/perf.md)
50 bool conductionGraph = false;
51 };
52
54 using GpuMultiresImplicitLimits = MultiresImplicitLimits; // 陰解法の系の大きさの上限(VRAM に先に取る。T-0178)
55
57 public:
58 GpuMultires(GpuMultires&& other) noexcept;
59 GpuMultires& operator=(GpuMultires&& other) noexcept;
60 GpuMultires(const GpuMultires&) = delete;
63
64 [[nodiscard]] static std::expected<GpuMultires, std::string> Create(ID3D12Device5* device,
65 const BakedReactionTable& table,
66 const MultiresCapacity& capacity,
67 const GpuMultiresOptions& options = {});
68
69 // CPU の木(状態・索引・取り合いの印)を GPU へ写す。大きさは Create と同じでなければならない
70 [[nodiscard]] bool RecordUpload(ID3D12GraphicsCommandList10* list, const MultiresNest& nest);
71
72 // --- 世界の木(multires_nest.h の SubmitRequests・ProcessRequests と同じ結果)---
73 // 要求の一覧を写す(一覧が空の時に。1 本のリストで REQUEST_UPLOAD_SLOTS 回まで)
74 [[nodiscard]] bool RecordRequests(ID3D12GraphicsCommandList10* list,
75 std::span<const multires::MrRequest> requests);
76 // 静かで一様になった頁を枠の順に畳む(FoldQuietPages と同じ。RecordQuietRequests の前。tick はこれから処理する刻み。T-0103)
77 void RecordFoldPages(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint64_t tick);
78 // 許容差つき(FoldQuietPages の許容差つきと同じ。ちょうど静かになった端数の枠を帳簿へ移して返し、ほぼ同じ頁も平均で畳む。T-0112)
79 void RecordFoldPages(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint64_t tick,
80 const multires::MrFoldTolerance& tolerance);
81 // 静かな本物の葉を粗くする要求を一覧の後ろに足す(SubmitQuietCoarsenRequests と同じ。RecordRequests の後・
82 // RecordProcessRequests の前。tick はこれから処理する刻み。T-0101)。粗くするのは子のセル 2×2×2 の組ごとの差が
83 // 許容差の中の葉だけ(TreeQuietCheck。D-430・T-0113)。許容差を渡さない版は完全に同じ時だけ
84 void RecordQuietRequests(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint64_t tick);
85 void RecordQuietRequests(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint64_t tick,
86 const multires::MrFoldTolerance& tolerance);
87 void RecordProcessRequests(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing);
88 // 頁を配る段(TreeExpand)だけ(計測用。刻む段が印を付けていなければ何も配らない。T-0102)
89 void RecordExpandPass(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing);
90
91 // --- 観察の枠(multires_nest.h の同じ名前の関数と同じ結果)---
92 void RecordRefineShadow(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing,
93 uint32_t parentSlot, uint32_t firstChildSlot, uint32_t levelCount,
94 const MultiresPoint& point);
95 void RecordRemoveShadow(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing,
96 uint32_t firstSlot, uint32_t levelCount);
97 // 全部を刻む(multires_nest.h の StepNest と同じ結果。options.conduction で熱の伝導も。T-0107。細かいレベルの小刻みも。T-0109)。
98 // 反応は待ちの丸め(ADR-0018。T-0121・T-0125)
99 void RecordStep(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint64_t worldSeed,
100 uint64_t tick, const MultiresStepOptions& options = {});
101 // 活性のブロックだけ刻む(multires_nest.h の StepActive と同じ結果。観察の枠は全部刻む。T-0100)。
102 // GpuMultiresOptions::activity で作っていなければ false。反応は待ちの丸め(T-0124。熱の伝導を入れる刻みも。T-0125)
103 [[nodiscard]] bool RecordStepActive(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing,
104 uint64_t worldSeed, uint64_t tick, const MultiresStepOptions& options = {});
105 void RecordPullBack(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing,
106 uint32_t firstShadowSlot, uint32_t levelCount);
107
108 // --- 外のバッファとパイプライン(T-0096)---
109 // u4・u5 に結ぶ外のバッファ。0 なら自分のセルのバッファを代わりに結ぶ(使わないシェーダーは読まない。ルートの引数は全部結ぶ約束)
110 void SetExternalViews(D3D12_GPU_VIRTUAL_ADDRESS first, D3D12_GPU_VIRTUAL_ADDRESS second);
111 // このルート署名で作った Compute のパイプラインを groupCount グループ起動する(外の定数は multires_bindings.hlsli の g_external*)
112 void RecordExternalDispatch(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing,
113 ID3D12PipelineState* pipeline, uint32_t groupCount,
114 const std::array<uint32_t, 4>& external);
115 [[nodiscard]] ID3D12RootSignature* RootSignature() const { return m_rootSignature.Get(); }
116 [[nodiscard]] uint32_t BlockCapacity() const { return m_blockCapacity; }
117
118 static constexpr uint32_t REQUEST_UPLOAD_SLOTS = 16;
119
120 // --- 読み戻し ---
121 void RecordReadback(ID3D12GraphicsCommandList10* list);
122 [[nodiscard]] bool Read(MultiresNest& nest) const;
123
124 // 次の刻みの活性の種(RecordReadback の時の一覧。枠の順・重なりなし)と、一覧が一杯で落とした数
126 std::vector<uint32_t> slots;
127 uint32_t dropped = 0;
128 };
129 [[nodiscard]] std::optional<ActivitySeeds> ReadSeeds() const;
130
131 // --- 計測: index 番目のタイムスタンプを打つ。RecordReadback が打った分を写し、ReadTimestamps で読む ---
132 void RecordTimestamp(ID3D12GraphicsCommandList10* list, uint32_t index);
133 [[nodiscard]] std::vector<uint64_t> ReadTimestamps(uint32_t count) const;
134
135 [[nodiscard]] uint64_t GraphBackingMemoryBytes() const { return m_graph->BackingMemoryBytes(); }
136
137 // 伝導の段を Work Graph で投げるか(計測で切り替える。conductionGraph で作っていなければ true にできず false を返す)
138 [[nodiscard]] bool UseConductionGraph(bool use);
139
140 // --- 細かいレベルの熱の陰解法(MultiresStepOptions::implicitConduction。T-0132)---
141 // 陰解法の段(系を作る・多重格子・解く・変化を足す)を上限の大きさで作る。implicitConduction の刻みの前に 1 回
142 [[nodiscard]] std::expected<void, std::string> EnableImplicitConduction(
143 ID3D12Device5* device, const GpuMultiresImplicitLimits& limits);
144 // 計測用: 陰解法の段の境にタイムスタンプを打つ(GpuMultiresImplicit::StampPhases)
145 void StampImplicitPhases(bool stamp);
146 // 陰解法の段(無ければ nullptr。最後に読み戻せた刻みの数を読む用)
147 [[nodiscard]] const GpuMultiresImplicit* ImplicitConduction() const { return m_implicit.get(); }
148
149 private:
150 // multires_bindings.hlsli の RootConstants と同じ並び
152 uint32_t seedLow = 0;
153 uint32_t seedHigh = 0;
154 uint32_t tickLow = 0;
155 uint32_t tickHigh = 0;
156 std::array<uint32_t, 6> point{}; // x・y・z の下位と上位
157 int32_t pointLevel = 0;
158 uint32_t blockCount = 0;
159 std::array<uint32_t, 4> external{}; // 外のパイプラインの定数(T-0096)
160
161 // --- 木の管理(T-0018)---
162 int32_t rootLevel = 0;
163 uint32_t worldBlocks = 0;
164 uint32_t indexEntries = 0;
165 uint32_t ledgerColumns = 0;
166 uint32_t graphInputLow = 0;
167 uint32_t graphInputHigh = 0;
168 uint32_t graphEntries = 0; // 下位 16bit = RefineNode、上位 16bit = CoarsenRequestNode
169
170 // --- 刻み(T-0107)---
171 uint32_t stepFlags = 0; // STEP_FLAG_*(multires_bindings.hlsli の MR_STEP_*)
172
173 // --- 頁を畳む(T-0112)---
174 uint32_t foldTolerance = 0; // MrPackFoldTolerance(0 = 完全に同じ)
175 };
176
177 // バッファの並び(u0〜u3、u6〜u12。multires_bindings.hlsli)
178 enum Buffer : uint8_t {
183 BufferTreeWords, // [世界の枠の空き][取り合いの印][索引][世界の頁の空き](T-0107 でまとめた)
188 BufferConduction, // 伝導の作業場(T-0107)
191 };
192
193 static constexpr uint32_t TABLE_COUNT = 4; // 物質・規則・索引・速度
194 static constexpr uint32_t ACTIVITY_LISTS = 2;
195 static constexpr uint32_t TREE_PASS_COUNT = 12;
196 static constexpr uint32_t CONDUCT_PASS_COUNT = 6;
197 static constexpr uint32_t MAX_TIMESTAMPS = 16;
198
199 GpuMultires() = default;
200
201 [[nodiscard]] std::expected<void, std::string> CreatePipelines(ID3D12Device5* device,
202 const GpuMultiresOptions& options);
203 [[nodiscard]] std::expected<void, std::string> CreateBuffers(ID3D12Device5* device,
204 const BakedReactionTable& table);
205 void BindRoot(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing) const;
206 void SetGraphProgram(ID3D12GraphicsCommandList10* list);
207 void SetActivityProgram(ID3D12GraphicsCommandList10* list);
208 void DispatchGraph(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t entry,
209 const void* record, uint32_t recordBytes);
210 void RecordTreePass(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t pass,
211 uint32_t groupCount);
212 [[nodiscard]] std::array<uint64_t, BufferCount> BufferSizes() const;
213 [[nodiscard]] uint64_t PageCount() const;
214 [[nodiscard]] uint64_t ConductRecordsOffset() const;
215 [[nodiscard]] std::vector<std::byte> MakeGraphInputImage() const;
216 void RecordExpandPages(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing);
217 // 待ちの丸め(T-0121): 起こす段(extraFlags に STEP_FLAG_WAKE_SEEDS なら種の一覧〔m_activityWrite〕に足す)・全部を刻む
218 void RecordWake(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t extraFlags);
219 void RecordStepWait(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing);
220 void RecordConductPass(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t pass,
221 uint32_t groupCount);
222 void RecordConduction(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing,
223 const MultiresStepOptions& options, uint32_t wakeList);
224 void RecordConductSubstep(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing,
225 const MultiresStepOptions& options);
226 void RecordSubstepEnd(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing,
227 uint32_t wakeList);
228 void RecordConductStage(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t pass);
229 void RecordImplicitConduction(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing,
230 const MultiresStepOptions& options);
231 [[nodiscard]] std::expected<void, std::string> CreateConductionGraph(ID3D12Device5* device);
232 [[nodiscard]] std::vector<std::byte> MakeTreeWordsImage(const MultiresNest& nest) const;
233 [[nodiscard]] uint64_t ActivityBytes() const;
234 [[nodiscard]] std::vector<std::byte> MakeActivityList(uint32_t list, std::span<const uint32_t> slots) const;
235 void SetTick(uint64_t worldSeed, uint64_t tick);
236
237 // --- 大きさ ---
239 uint32_t m_blockCapacity = 0; // 世界の枠 + 観察の枠
240
241 // --- パイプライン ---
242 ComPtr<ID3D12RootSignature> m_rootSignature;
243 // --- 待ちの丸め(T-0121)---
244 ComPtr<ID3D12PipelineState> m_wakePipeline; // 起こす段: 見出しを全部なめる
245 ComPtr<ID3D12PipelineState> m_stepWaitPipeline; // 全部の枠を刻む(1 グループ = 1 枠)
246 ComPtr<ID3D12PipelineState> m_stepExpandedWaitPipeline; // 頁に広げたブロックを埋めて刻む
247 std::array<ComPtr<ID3D12PipelineState>, TREE_PASS_COUNT> m_treePipelines;
248 std::array<ComPtr<ID3D12PipelineState>, CONDUCT_PASS_COUNT> m_conductPipelines; // 熱の伝導の段(T-0107)
249 std::unique_ptr<gpu::WorkGraph> m_conductGraph; // 伝導の段の Work Graph 版(無ければ Compute だけ)
251 bool m_useConductGraph = false;
252 std::array<uint32_t, 4> m_conductEntries = {UINT32_MAX, UINT32_MAX, UINT32_MAX,
253 UINT32_MAX}; // 埋める・流れ・足す・小刻みの終わり
254 std::unique_ptr<gpu::WorkGraph> m_graph;
255 bool m_graphInitialized = false;
256 std::array<uint32_t, 4> m_entries{}; // 細かくする・粗くする要求・引き戻す・影を捨てる
257 std::unique_ptr<gpu::WorkGraph> m_activityGraph; // 無ければ活性を使わない
259 std::array<uint32_t, 3> m_activityEntries = {UINT32_MAX, UINT32_MAX,
260 UINT32_MAX}; // 活性の種・観察の枠を刻む・頁に広げて刻む
262
263 // --- バッファ(既定のヒープ・アップロード・読み戻し。並びは Buffer の順)---
264 std::array<ComPtr<ID3D12Resource>, BufferCount> m_buffers;
265 std::array<ComPtr<ID3D12Resource>, BufferCount> m_uploads;
266 std::array<ComPtr<ID3D12Resource>, BufferCount> m_readbacks;
267 ComPtr<ID3D12Resource> m_requestUpload; // REQUEST_UPLOAD_SLOTS × (要求の数 + 一覧)
269 std::array<ComPtr<ID3D12Resource>, TABLE_COUNT> m_tables;
270 std::array<D3D12_GPU_VIRTUAL_ADDRESS, 2> m_externalViews{}; // u4・u5(0 なら代わりにセル)
271
272 // --- 活性の種の一覧(T-0100。MR_ACTIVITY_*)---
273 std::array<ComPtr<ID3D12Resource>, ACTIVITY_LISTS> m_activity;
274 ComPtr<ID3D12Resource> m_activityUpload; // 最初の一覧 + 空の一覧 2 本
275 ComPtr<ID3D12Resource> m_activityReadback; // 次の刻みの種の一覧
276 uint32_t m_activityCurrent = 0; // この刻みの種の一覧
277 uint32_t m_activityWrite = 0; // u13 に結ぶ一覧
278
279 // --- 細かいレベルの熱の陰解法(T-0132。EnableImplicitConduction で作る)---
280 std::unique_ptr<GpuMultiresImplicit> m_implicit;
281
282 // --- 計測 ---
283 ComPtr<ID3D12QueryHeap> m_timestamps;
284 ComPtr<ID3D12Resource> m_timestampReadback;
285 uint32_t m_timestampCount = 0;
286 };
287
288} // namespace bicameral::sim
static constexpr uint32_t CONDUCT_PASS_COUNT
std::array< uint32_t, 4 > m_entries
ComPtr< ID3D12RootSignature > m_rootSignature
GpuMultires & operator=(GpuMultires &&other) noexcept
void StampImplicitPhases(bool stamp)
void RecordQuietRequests(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint64_t tick)
ComPtr< ID3D12Resource > m_timestampReadback
void BindRoot(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing) const
uint64_t GraphBackingMemoryBytes() const
void SetActivityProgram(ID3D12GraphicsCommandList10 *list)
ComPtr< ID3D12QueryHeap > m_timestamps
std::unique_ptr< gpu::WorkGraph > m_conductGraph
void SetTick(uint64_t worldSeed, uint64_t tick)
static constexpr uint32_t TREE_PASS_COUNT
uint64_t ConductRecordsOffset() const
void RecordExpandPages(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing)
GpuMultires & operator=(const GpuMultires &)=delete
ComPtr< ID3D12PipelineState > m_wakePipeline
static constexpr uint32_t TABLE_COUNT
std::array< ComPtr< ID3D12Resource >, BufferCount > m_readbacks
bool RecordRequests(ID3D12GraphicsCommandList10 *list, std::span< const multires::MrRequest > requests)
void RecordFoldPages(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint64_t tick, const multires::MrFoldTolerance &tolerance)
void RecordWake(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t extraFlags)
std::unique_ptr< gpu::WorkGraph > m_activityGraph
void RecordFoldPages(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint64_t tick)
void RecordConduction(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, const MultiresStepOptions &options, uint32_t wakeList)
std::array< ComPtr< ID3D12Resource >, TABLE_COUNT > m_tables
void RecordStepWait(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing)
std::vector< uint64_t > ReadTimestamps(uint32_t count) const
void SetGraphProgram(ID3D12GraphicsCommandList10 *list)
void SetExternalViews(D3D12_GPU_VIRTUAL_ADDRESS first, D3D12_GPU_VIRTUAL_ADDRESS second)
ID3D12RootSignature * RootSignature() const
void RecordConductStage(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t pass)
void RecordRefineShadow(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t parentSlot, uint32_t firstChildSlot, uint32_t levelCount, const MultiresPoint &point)
static constexpr uint32_t MAX_TIMESTAMPS
bool Read(MultiresNest &nest) const
std::vector< std::byte > MakeTreeWordsImage(const MultiresNest &nest) const
std::array< uint64_t, BufferCount > BufferSizes() const
void RecordPullBack(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t firstShadowSlot, uint32_t levelCount)
void DispatchGraph(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t entry, const void *record, uint32_t recordBytes)
const GpuMultiresImplicit * ImplicitConduction() const
ComPtr< ID3D12Resource > m_activityReadback
ComPtr< ID3D12PipelineState > m_stepExpandedWaitPipeline
std::vector< std::byte > MakeActivityList(uint32_t list, std::span< const uint32_t > slots) const
std::array< ComPtr< ID3D12Resource >, BufferCount > m_uploads
void RecordImplicitConduction(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, const MultiresStepOptions &options)
ComPtr< ID3D12Resource > m_requestUpload
std::array< ComPtr< ID3D12Resource >, BufferCount > m_buffers
std::array< ComPtr< ID3D12Resource >, ACTIVITY_LISTS > m_activity
void RecordConductPass(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t pass, uint32_t groupCount)
void RecordExternalDispatch(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, ID3D12PipelineState *pipeline, uint32_t groupCount, const std::array< uint32_t, 4 > &external)
MultiresCapacity m_capacity
ComPtr< ID3D12PipelineState > m_stepWaitPipeline
static constexpr uint32_t ACTIVITY_LISTS
void RecordRemoveShadow(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t firstSlot, uint32_t levelCount)
std::vector< std::byte > MakeGraphInputImage() const
void RecordTimestamp(ID3D12GraphicsCommandList10 *list, uint32_t index)
void RecordQuietRequests(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint64_t tick, const multires::MrFoldTolerance &tolerance)
std::array< uint32_t, 3 > m_activityEntries
void RecordStep(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint64_t worldSeed, uint64_t tick, const MultiresStepOptions &options={})
std::expected< void, std::string > CreateBuffers(ID3D12Device5 *device, const BakedReactionTable &table)
std::expected< void, std::string > CreatePipelines(ID3D12Device5 *device, const GpuMultiresOptions &options)
bool RecordUpload(ID3D12GraphicsCommandList10 *list, const MultiresNest &nest)
ComPtr< ID3D12Resource > m_activityUpload
void RecordExpandPass(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing)
bool RecordStepActive(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint64_t worldSeed, uint64_t tick, const MultiresStepOptions &options={})
static std::expected< GpuMultires, std::string > Create(ID3D12Device5 *device, const BakedReactionTable &table, const MultiresCapacity &capacity, const GpuMultiresOptions &options={})
std::unique_ptr< GpuMultiresImplicit > m_implicit
void RecordSubstepEnd(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t wakeList)
std::unique_ptr< gpu::WorkGraph > m_graph
void RecordConductSubstep(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, const MultiresStepOptions &options)
std::array< uint32_t, 4 > m_conductEntries
std::optional< ActivitySeeds > ReadSeeds() const
GpuMultires(const GpuMultires &)=delete
void RecordProcessRequests(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing)
void RecordReadback(ID3D12GraphicsCommandList10 *list)
std::expected< void, std::string > EnableImplicitConduction(ID3D12Device5 *device, const GpuMultiresImplicitLimits &limits)
uint32_t BlockCapacity() const
std::expected< void, std::string > CreateConductionGraph(ID3D12Device5 *device)
std::array< ComPtr< ID3D12PipelineState >, TREE_PASS_COUNT > m_treePipelines
std::array< ComPtr< ID3D12PipelineState >, CONDUCT_PASS_COUNT > m_conductPipelines
std::array< D3D12_GPU_VIRTUAL_ADDRESS, 2 > m_externalViews
static constexpr uint32_t REQUEST_UPLOAD_SLOTS
GpuMultires(GpuMultires &&other) noexcept
void RecordTreePass(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, uint32_t pass, uint32_t groupCount)
MultiresImplicitLimits GpuMultiresImplicitLimits