Bicameral Engine
GPU-resident engine for a magic-research open-world game
Loading...
Searching...
No Matches
probe_sim.h
Go to the documentation of this file.
1// probe_sim.h — 仮の刻み(shaders/common/probe_sim.hlsli)を「単位」の列として GPU で走らせる道具と、その CPU リファレンス
2// (T-0004・T-0012・T-0086・T-0005)。
3//
4// 刻みのループの形(06 §4・ADR-0011)と、Work Graphs の伝播(T-0005)を確かめる。中身(64³ のセルの成分 + エネルギー、温度の差の伝導と
5// 反応。T-0089。初めは空気の中の木箱)は段ごとに本物に置き換える:
6// - 伝導の単位は Work Graph(shaders/sim/probe_conduct.hlsl)。入力は GPU が作る活性の一覧(DispatchGraph の GPU の入力)なので、
7// どこが活性か・何ブロック計算するかを CPU は知らない(D-107)。熱が広がっている所だけが計算される。
8// - 1 刻み = 決まった数の単位(適用 → 伝導 → 重さ × k → ハッシュ)。フレームの切れ目はどの単位の間にも来てよい(刻みはフレームをまたぐ)。
9// - CPU は毎フレーム、そのフレームに投げる単位(何番目の刻みの何番目から何個)を、フレームの枠ごとのリストに記録して投げる。
10// 同じリストは前の実行が終わるまで投げ直せない(debug layer [553])ので、使い回す記録済みのリストではなく毎フレーム記録する。
11// CPU が書くのはコマンドの並び・ルート定数・Dispatch だけ(世界の状態には触れない。D-107)。
12// - 単位ごとのタイムスタンプを取り、CPU は単位の GPU 時間から次のフレームに投げる数を決める(frame/sim_scheduler)。
13// - 刻みの最後の単位が状態のハッシュを GPU で取り、刻みの中のイベントを並べてリングへ写す(06 §2 段 9)。フレームの終わりに CPU へ読み戻す(待たない)。
14// - コマンドはフレームのリストの先頭で GPU のコマンドキューへ足す。コマンドは自分の刻みの適用の単位まで GPU で待つ(06 §3)。
15// CPU の約束: 足すコマンドは (targetTick, sequence) の昇順で、targetTick はまだ記録していない最初の適用の刻み(NextApplyTick)以上、
16// 数は FreeCommandSlots() 以下(RecordFrame が確かめる)。
17// - 抽出(描画が読む)は、投げた単位の後ろで、刻みの境界の状態を写す(1 フレームに 1 回まで)。
18//
19// 使い方:
20// auto table = BakeReactionTable(MakeCombustionTestTable()); // ランタイムは script::LoadReactionTable(T-0157)
21// auto sim = ProbeSim::Create(device, D3D12_COMMAND_LIST_TYPE_COMPUTE, *table, {.busyIterations = n, .busyPieces = k});
22// ID3D12CommandList* list = sim->RecordFrame(slot, {.firstTick = t, .firstUnit = u, .unitCount = c, .commands = 新しいコマンド, ...});
23// computeQueue.Submit(list) → フェンスが進んだら sim->ReadFrame(slot)
24// 浮動小数点は使わない(engine/src/sim は検査の対象。04 §4)。
25#pragma once
26
27#include <array>
28#include <cstdint>
29#include <expected>
30#include <functional>
31#include <memory>
32#include <span>
33#include <string>
34#include <vector>
35
36#include "common/probe_sim.hlsli"
37#include "common/probe_world.hlsli"
38#include "gpu/com_ptr.h"
39#include "gpu/debug_ring.h"
40#include "gpu/graph_trace.h"
41#include "gpu/readback_ring.h"
42#include "gpu/work_graph.h"
44#include "sim/command.h"
45#include "sim/gpu_physics.h"
46#include "sim/physics_scene.h"
47#include "sim/reaction_table.h"
48
49namespace bicameral::sim {
50
51 // --- コマンド(06 §3 の 64 バイト。sim/command.h)---
52
54 static_assert(sizeof(ProbeCommand) == PROBE_COMMAND_BYTES);
55
56 // 反応表の差し替えの印(PROBE_COMMAND_TYPE_TABLE。T-0139・ADR-0047)。GPU の適用は何もせず、記録と再生に「刻み targetTick の始めに
57 // 版 version の表に変わった」を残す。表そのものは同じ刻みの ProbeFrameInput::tableSwap で渡す
58 [[nodiscard]] ProbeCommand MakeTableCommand(uint64_t targetTick, uint32_t sequence, uint64_t version);
59 [[nodiscard]] inline uint64_t TableCommandVersion(const ProbeCommand& command) {
60 return uint64_t{command.payload[0]} | (uint64_t{command.payload[1]} << 32);
61 }
62
63 // セル (x, y, z) を約 2700 K 温める熱を足す(PROBE_POKE_HEATING_MILLIKELVIN。明示的な湧き出し)
64 [[nodiscard]] ProbeCommand MakePokeCommand(uint64_t targetTick, uint32_t sequence, uint32_t x, uint32_t y,
65 uint32_t z);
66
67 // 光線で物を押す(T-0098。PROBE_COMMAND_TYPE_PUSH)。origin は物理の座標(2^-20 m)、direction は長さ 1 の Q1.30、力積は mN·s
68 [[nodiscard]] ProbeCommand MakePushCommand(uint64_t targetTick, uint32_t sequence,
69 const std::array<int64_t, 3>& origin,
70 const std::array<int32_t, 3>& direction,
71 uint32_t impulseMillinewtonSeconds);
72
73 // --- GPU から戻ってくるもの ---
74
75 struct ProbeEvent {
76 uint64_t tick = 0;
77 uint32_t type = 0; // PROBE_EVENT_*
78 uint32_t place = 0; // つつき: x | y << 8 | z << 16(ProbePokePlace)。遅れたコマンド: コマンドの種類
79
80 [[nodiscard]] uint32_t PokeX() const { return place & 0xFFu; }
81 [[nodiscard]] uint32_t PokeY() const { return (place >> 8) & 0xFFu; }
82 [[nodiscard]] uint32_t PokeZ() const { return (place >> 16) & 0xFFu; }
83 friend bool operator==(const ProbeEvent&, const ProbeEvent&) = default;
84 };
85
86 // 刻み tick の始めの状態 S(tick) の要約(ハッシュの表の欄。probe_sim.hlsli)
88 uint64_t tick = 0;
89 uint64_t hash = 0; // ProbeStateHash
90 uint64_t energy = 0; // エネルギーの合計(ProbeEnergySum。mJ の和の mod 2^64)
91 uint64_t sourceEnergy =
92 0; // S(tick) を作った刻み(tick − 1)のつつきが足したエネルギー(mJ)。energy(t) = energy(t − 1) + これ
93 uint32_t scheduledBlocks = 0; // S(tick) を作った刻み(tick − 1)で伝導と反応を計算したブロックの数
94 uint64_t bodyHash = 0; // 物の状態のハッシュ(PhysicsWorld::StateHash。物理なしなら 0。T-0098)
95
96 // 世界全体の要約(セル + 物。再生ファイルに入れて突き合わせる値)
97 [[nodiscard]] uint64_t WorldHash() const { return hash ^ bodyHash; }
98 };
99
101 // --- 世界の結果 ---
102 std::vector<ProbeEvent> events; // (刻み, 種類, 場所) の順(刻みの最後に GPU が並べる。分け方に依存しない)
103 uint32_t droppedEventCount = 0; // 容量を超えて書けなかった数(刻みの一時置き場 + リング)
104 std::vector<ProbeTickHash> hashes; // このフレームで終えた刻みの状態(刻みの順)
105
106 // --- GPU の時間 ---
107 std::vector<uint64_t> unitGpuTicks; // 投げた i 番目の単位の GPU 時間(タイムスタンプの刻み)
108 uint32_t firstUnit = 0; // unitGpuTicks[0] の単位の、刻みの中の番号
109 uint64_t gpuBeginTimestamp = 0; // リスト全体(抽出と読み戻しを含む)の始めと終わり
110 uint64_t gpuEndTimestamp = 0;
111
112 // --- デバッグ ---
113 uint32_t debugAssertCount = 0; // シェーダーの assert の数(中身はログに出る)
114
115 // 伝導のグラフのノードごとのカウンタ(このフレームの全部の刻みの合計。T-0008)
117 uint32_t graphFindingCount = 0; // 上限に当たった・近づいたものの数(中身は Warning でログに出る)
118
119 // 伝導の連鎖のトレース(範囲を有効にしたときだけ。atomic の順。T-0087。組み立ては sim/probe_trace.h)
120 std::vector<gpu::GraphTraceRecord> trace;
121 uint32_t droppedTraceCount = 0; // 容量を越えて書けなかった数(> 0 ならトレースは欠けている)
122 };
123
124 // 抽出の後のフック(ProbeFrameInput::afterExtract)に渡すもの(T-0096)
126 uint64_t tick = 0; // 抽出した刻みの境界(S(tick)。セルの世代は tick & 1)
127 ID3D12Resource* cells = nullptr; // 世界のセル(UAV の状態。読むだけ)
128 ID3D12Resource* extraction = nullptr; // 書き終えた抽出(UAV の状態)
129 D3D12_GPU_VIRTUAL_ADDRESS debugRing = 0; // シミュのデバッグのリング(FX_ASSERT の出力。ReadFrame でログへ出る)
130 };
131
132 // 保存点を使わない(ProbeFrameInput::saveTo・restoreFrom の既定)
133 inline constexpr uint32_t NO_SAVE_POINT = UINT32_MAX;
134
135 // 反応表の差し替え(ホットリロード。T-0139・ADR-0047)。刻み tick の適用の単位の前に table を写し(コマンドの適用から新しい表)、
136 // 適用の後に熱のキャッシュを作り直して全部のブロックを起こす(RefreshTable)。呼ぶ側の約束: table の物質の一覧が今の表と同じ
137 // (セルの物質 ID の意味が変わらない。script::CheckHotReloadCompatible)・(tick, 0) の単位がこのフレームにある・同じ刻みに
138 // MakeTableCommand の印を足す(記録と再生のため)。table は RecordFrame の中で写し終わる(呼んだ後は持たなくてよい)。
139 // 1 フレームに幾つあってもよい(刻みの順でなくてよい。同じ刻みに 2 つは不可)
141 uint64_t tick = 0;
142 const BakedReactionTable* table = nullptr; // nullptr なら差し替えない
143 };
144
146 uint64_t firstTick = 0; // 最初の単位の刻み
147 uint32_t firstUnit = 0; // 最初の単位の、刻みの中の番号(0〜UnitsPerTick()-1)
148 uint32_t unitCount = 0; // 投げる単位の数(0〜MAX_UNITS_PER_FRAME。0 なら抽出だけ)
149
150 bool extract = false; // 単位の後ろで、刻みの境界の状態を抽出へ写すか
151 uint32_t extractionTarget = 0; // 抽出の書き先(0〜PROBE_EXTRACTION_COUNT-1)
152
153 // GPU のキューへ足す新しいコマンド(最大 PROBE_MAX_COMMANDS。約束はファイルの先頭)
154 std::span<const ProbeCommand> commands;
155
156 // 物理の物と統計を、フレームの終わりに読み戻す(テスト用。T-0098)。読み戻しの置き場は 1 つなので、そのリストが終わってから
157 // 次に読み戻すリストを投げるまでに Physics()->ReadBodies() / ReadStats() を呼ぶ。このフレームに単位があること
158 bool readPhysics = false;
159
160 // 抽出の後に同じリストへ記録するもの(覗き窓 sim/probe_peek。T-0096)。抽出するフレームだけ呼ぶ。
161 // 約束: 世界のバッファは読むだけ、抽出は覗きの欄だけに書く(世界の結果を変えない。D-403)
162 std::function<void(ID3D12GraphicsCommandList10* list, const ProbeExtractContext& context)> afterExtract;
163
164 // --- 巻き戻し(T-0143。sim/probe_save_point.cpp)。どちらも刻みの境界から始まるフレーム(firstUnit == 0)だけ・同時には使えない ---
165 // 単位の前に、S(firstTick) をこの番号の保存点へ写す(GPU → GPU。CreateSavePoints の後)
167 // 単位の前に、世界をこの番号の保存点の状態へ戻す(firstTick は保存点の刻み)。GPU のキューで待っていたコマンドは捨てる
168 // (呼ぶ側が firstTick 以降のコマンドを、このフレームの commands から足し直す)
170
171 // --- 反応表の差し替え(T-0139)---
172 std::span<const ProbeTableSwap> tableSwaps;
173 };
174
175 // 重さの試験(R-LOOP-2)。世界の結果には入らない
177 // 1 刻みに足す繰り返しの合計(0 なら重さの単位は無し。上限 PROBE_BUSY_ITERATIONS_LIMIT)
178 uint32_t busyIterations = 0;
179 uint32_t busyPieces = 1; // それを何個の単位に分けるか(1〜PROBE_MAX_BUSY_PIECES)
180
181 // 伝導の連鎖のトレースの最初の範囲(既定は無効。場所の箱はブロックの座標。セルからは ProbeTraceFilterForCells。T-0087)
183
184 // トレースの容量(1 フレームに書ける記録の上限)。実行中に SetTraceFilter で範囲を変えるなら上限ぶんを渡す(T-0088)。
185 // 0 なら trace.capacity だけ
186 uint32_t traceCapacity = 0;
187
188 // 物理の場面(T-0098。nullptr なら物理の単位は無い)。物の 1 刻みを伝導の後ろの単位に入れ、押すコマンドを受け付ける。
189 // 呼んだ後は持たなくてよい
190 const PhysicsScene* physicsScene = nullptr;
192 physicsOptions; // 物理の解き方(既定は T-0092 で測った形: 広域と接触は Work Graph・色ごとの解は Compute)
193 physics::PxParameters physicsParameters = physics::PxDefaultParameters();
194
195 // 初めの世界(PROBE_CELL_COUNT 個。空なら MakeProbeInitialWorld。試験用。T-0122)。作る時だけ読む(呼んだ後は持たなくてよい)
196 std::span<const reaction::RxCell> initialWorld;
197 };
198
199 // --- GPU で走らせる ---
200
201 class ProbeSim {
202 public:
203 static constexpr uint32_t FRAME_SLOT_COUNT = 4; // 同時に GPU にあってよいフレームのリストの数
204 static constexpr uint32_t MAX_UNITS_PER_FRAME = 256;
205
206 // listType: フレームのリストを投げるキューの種類(シミュは compute。06 §4)
207 // table: 反応の表(ベイクしたもの)。GPU に写し、初めの世界(MakeProbeInitialWorld)も作る。呼んだ後は持たなくてよい
208 [[nodiscard]] static std::expected<ProbeSim, std::string> Create(ID3D12Device5* device,
209 D3D12_COMMAND_LIST_TYPE listType,
210 const BakedReactionTable& table,
211 const ProbeSimOptions& options = {});
212
213 // 1 刻みの単位の数(適用・伝導・ハッシュ + 重さの単位)
214 [[nodiscard]] uint32_t UnitsPerTick() const {
215 return PROBE_FIXED_UNITS_PER_TICK + PhysicsUnitCount() + BusyUnitCount();
216 }
217
218 [[nodiscard]] uint32_t HashUnit() const { return UnitsPerTick() - 1; }
219
220 // 次に記録する単位が (tick, unit) のとき、まだ記録していない最初の適用の単位の刻み。
221 // そのフレームに足すコマンドの targetTick はこれ以上でなければならない(でなければ適用に間に合わない)
222 [[nodiscard]] static uint64_t NextApplyTick(uint64_t tick, uint32_t unit) {
223 return unit == 0 ? tick : tick + 1;
224 }
225
226 // GPU のコマンドキューの空き(記録した適用の単位で取り出される分を引いた、次のフレームに足せる数)
227 [[nodiscard]] uint32_t FreeCommandSlots() const { return PROBE_COMMAND_QUEUE_CAPACITY - m_queuedCommandCount; }
228
229 // slot のアップロードのバッファに入力を書き、slot のリストに単位を記録して返す。
230 // 呼ぶ側の約束: slot の前のリストを GPU が終えている。入力が範囲外・記録の失敗なら nullptr(理由はログ)
231 [[nodiscard]] ID3D12CommandList* RecordFrame(uint32_t slot, const ProbeFrameInput& input);
232
233 // slot のリストを GPU が終えた後に呼ぶ(待たない。終わったかどうかは呼ぶ側がフェンスで見る)。
234 // ノードのカウンタの要約と上限の Warning もここでログへ出す(同じ Warning を繰り返しすぎないように状態を持つので const でない)
235 [[nodiscard]] ProbeFrameReadback ReadFrame(uint32_t slot);
236
237 // 伝導の連鎖のトレースの範囲を変える。次に記録するフレームから効く(容量は作った時の容量までに切り詰める。T-0088)
238 void SetTraceFilter(const gpu::GraphTraceFilter& filter) { m_graphTrace.SetFilter(filter); }
239 [[nodiscard]] const gpu::GraphTraceFilter& TraceFilter() const { return m_graphTrace.Filter(); }
240
241 // 伝導のグラフのカウンタの名前と上限(フレームのループが要約をまとめて出すときに使う)
242 [[nodiscard]] const gpu::GraphStatsLayout& ConductStatsLayout() const { return m_graphStats.Layout(); }
243
244 // 描画用の抽出(0〜PROBE_EXTRACTION_COUNT-1。全部のセルの温度と見る物質 3 つの量 + ブロックの活性の印、PROBE_EXTRACTION_WORDS 個。
245 // 並びは probe_sim.hlsli)。描画は読むだけ
246 [[nodiscard]] ID3D12Resource* Extraction(uint32_t target) const { return m_extractions[target].Get(); }
247
248 // 世界のセル(2 世代 × PROBE_CELL_COUNT × RxCell。S(t) は世代 t & 1)。テストが読み戻すだけ(フレームの間は COMMON)
249 [[nodiscard]] ID3D12Resource* Cells() const { return m_cells.Get(); }
250
251 // 伝導の Work Graph の裏のメモリ(ドライバが決める。docs/perf.md に残す)
252 [[nodiscard]] uint64_t ConductBackingMemoryBytes() const { return m_conductGraph->BackingMemoryBytes(); }
253
254 // 物理(物理なしなら nullptr。T-0098)。テストが読み戻しを読むだけ(記録はフレームのリストの中で ProbeSim がする)
255 [[nodiscard]] const GpuPhysics* Physics() const { return m_physics.get(); }
256
257 // --- 巻き戻し(保存点 + 再生。T-0143・ADR-0036。sim/probe_save_point.cpp)---
258 // 保存点(刻みの境界の状態の写し。VRAM に置く)を count 個作る。作り直すと前の保存点は消える
259 [[nodiscard]] bool CreateSavePoints(ID3D12Device5* device, uint32_t count);
260 [[nodiscard]] uint32_t SavePointCount() const { return static_cast<uint32_t>(m_savePoints.size()); }
261 // その保存点が持つ状態の刻み(まだ写していなければ UINT64_MAX)。写すリストを記録した時に決まる(GPU が終えたかは呼ぶ側がフェンスで見る)
262 [[nodiscard]] uint64_t SavePointTick(uint32_t index) const {
263 return index < m_savePoints.size() ? m_savePoints[index].tick : UINT64_MAX;
264 }
265 // tick より後の刻みの保存点を空にする(巻き戻した後、その先の流れが変わりうるので)
266 void DiscardSavePointsAfter(uint64_t tick) {
267 for (SavePoint& savePoint : m_savePoints) {
268 if (savePoint.tick != UINT64_MAX && savePoint.tick > tick)
269 savePoint.tick = UINT64_MAX;
270 }
271 }
272 // 保存点 1 つの大きさ(docs/perf.md)
273 [[nodiscard]] uint64_t SavePointBytes() const;
274
275 private:
276 struct FrameSlot {
277 // --- 記録 ---
278 ComPtr<ID3D12CommandAllocator> allocator;
279 ComPtr<ID3D12GraphicsCommandList10> list; // 毎フレーム記録し直す
280
281 // --- 入力 ---
282 ComPtr<ID3D12Resource> input; // アップロード(PROBE_INPUT_BYTES)
283 std::byte* mappedInput = nullptr; // Map したまま
284
285 // --- 読み戻し ---
286 ComPtr<ID3D12Resource> timestampReadback; // (MAX_UNITS_PER_FRAME + 2) × 8 バイト
287 ComPtr<ID3D12Resource> hashReadback; // PROBE_HASH_BYTES
288
289 // 反応表を差し替えたフレームの、表のアップロードと差し替える前の表(このリストを GPU が終えるまで持つ。T-0139)
290 std::vector<ComPtr<ID3D12Resource>> keepAlive;
291
292 // 最後に記録した範囲(ReadFrame が、どの刻みのハッシュとどの単位の時間かを知るため)
293 uint64_t firstTick = 0;
294 uint32_t firstUnit = 0;
295 uint32_t unitCount = 0;
296 };
297
298 ProbeSim(const ProbeSimOptions& options, gpu::ReadbackRing&& events, gpu::DebugRing&& debugRing,
299 gpu::WorkGraphStats&& graphStats, gpu::GraphTrace&& graphTrace)
300 : m_options(options),
301 m_events(std::move(events)),
302 m_debugRing(std::move(debugRing)),
303 m_graphStats(std::move(graphStats)),
304 m_graphTrace(std::move(graphTrace)) {}
305
306 [[nodiscard]] uint32_t BusyUnitCount() const { return m_options.busyIterations > 0 ? m_options.busyPieces : 0; }
307 [[nodiscard]] uint32_t PhysicsUnitCount() const { return m_physics ? 1 : 0; }
308
309 // --- 作る ---
310 [[nodiscard]] bool CreatePipelines(ID3D12Device5* device);
311 [[nodiscard]] bool CreateConductGraph(ID3D12Device5* device);
312 [[nodiscard]] bool CreateBuffers(ID3D12Device5* device);
313 [[nodiscard]] bool CreateWorld(ID3D12Device5* device, const BakedReactionTable& table,
314 std::span<const reaction::RxCell> initialWorld);
315 void RecordInitialization(ID3D12GraphicsCommandList10* list);
316 [[nodiscard]] bool CreateFrameSlots(ID3D12Device5* device, D3D12_COMMAND_LIST_TYPE listType);
317 [[nodiscard]] std::expected<void, std::string> CreatePhysics(ID3D12Device5* device);
318
319 // --- 入力とコマンド ---
320 [[nodiscard]] bool ValidateInput(uint32_t slot, const ProbeFrameInput& input) const;
321 [[nodiscard]] bool ValidateCommands(const ProbeFrameInput& input) const;
322 void WriteInput(FrameSlot& frame, const ProbeFrameInput& input) const;
323 void RecordEnqueue(ID3D12GraphicsCommandList10* list, uint32_t commandCount) const;
324 void TrackCommands(std::span<const ProbeCommand> commands, uint64_t nextApplyTick);
325
326 // --- 単位の記録 ---
327 void BindRootArguments(ID3D12GraphicsCommandList10* list, ID3D12Resource* input) const;
328 void BindRootViews(ID3D12GraphicsCommandList10* list, ID3D12Resource* input) const;
329 void RecordUnit(ID3D12GraphicsCommandList10* list, ID3D12Resource* input, uint64_t tick, uint32_t unit,
330 bool tableSwapped);
331 [[nodiscard]] bool ValidateTableSwap(const ProbeFrameInput& input) const;
332 [[nodiscard]] bool RecordTableSwap(ID3D12GraphicsCommandList10* list, FrameSlot& frame,
333 const BakedReactionTable& table);
334 void RecordConduct(ID3D12GraphicsCommandList10* list, ID3D12Resource* input, uint64_t tick);
335 void RecordPhysics(ID3D12GraphicsCommandList10* list, ID3D12Resource* input, uint64_t tick);
336 void RecordPhysicsInitialization(ID3D12GraphicsCommandList10* list, ID3D12Resource* input);
337 void RecordActiveListStates(ID3D12GraphicsCommandList10* list, D3D12_RESOURCE_STATES before,
338 D3D12_RESOURCE_STATES after) const;
339 void RecordExtract(ID3D12GraphicsCommandList10* list, uint64_t tick, uint32_t target) const;
340 void RecordExtractAndHook(ID3D12GraphicsCommandList10* list, uint64_t tick, const ProbeFrameInput& input);
341
342 // --- 読み戻し ---
343 void RecordReadbacks(ID3D12GraphicsCommandList10* list, uint32_t slot, bool hasHash) const;
344
345 // --- 巻き戻し(sim/probe_save_point.cpp)---
346 // 保存点に写す世界の部分。generationBytes > 0 のもの(セル・熱)は S(tick) の世代だけを写し、戻すときは 2 世代に写す
347 // (予定していないブロックは 2 世代とも S(t) と同じ値。予定したブロックは刻み t がもう一方の世代を全部書き直す。probe_sim.hlsli)
348 struct StateRegion {
349 ID3D12Resource* resource = nullptr;
350 uint64_t offset = 0;
351 uint64_t bytes = 0;
352 uint64_t generationBytes = 0;
353 };
354
355 struct SavePoint {
356 uint64_t tick = UINT64_MAX; // UINT64_MAX = 空
357 std::vector<ComPtr<ID3D12Resource>> buffers; // StateRegions の順
359 };
360
361 [[nodiscard]] std::vector<StateRegion> StateRegions(uint64_t tick) const;
362 [[nodiscard]] bool ValidateSavePoints(const ProbeFrameInput& input) const;
363 void RecordSave(ID3D12GraphicsCommandList10* list, uint32_t index, uint64_t tick);
364 void RecordRestore(ID3D12GraphicsCommandList10* list, uint32_t index);
365 void ResetCommandMirror();
366 [[nodiscard]] std::vector<ProbeTickHash> ReadHashes(const FrameSlot& frame) const;
367
369
370 // --- パイプライン ---
371 ComPtr<ID3D12RootSignature> m_rootSignature;
372 ComPtr<ID3D12PipelineState> m_enqueuePipeline;
373 ComPtr<ID3D12PipelineState> m_applyPipeline;
374 ComPtr<ID3D12PipelineState> m_wakeDuePipeline; // 起こす刻みの来たブロックを一覧へ(待ちの丸め。T-0122)
375 ComPtr<ID3D12PipelineState>
376 m_refreshTablePipeline; // 表を差し替えた刻み: 熱のキャッシュと全部のブロックを起こす(T-0139)
377 ComPtr<ID3D12PipelineState> m_busyPipeline;
378 ComPtr<ID3D12PipelineState> m_hashCellsPipeline;
379 ComPtr<ID3D12PipelineState> m_flushEventsPipeline;
380 ComPtr<ID3D12PipelineState> m_extractPipeline;
381
382 // --- 伝導の Work Graph ---
383 std::unique_ptr<gpu::WorkGraph> m_conductGraph; // 伝導(shaders/sim/probe_conduct.hlsl)
384 uint32_t m_conductEntrypoint = 0; // WakeBlocks の入口の番号
385 bool m_conductInitialized = false; // 裏のメモリを初期化するリストを記録したか(最初の 1 回だけ)
386
387 // --- 世界と抽出 ---
388 ComPtr<ID3D12Resource> m_cells; // 2 世代 × PROBE_CELL_COUNT × RxCell
389 ComPtr<ID3D12Resource> m_thermal; // 2 世代 × PROBE_CELL_COUNT × HcThermalCache
390 // 反応の表(物質・規則・索引・速度。既定のヒープ)と、初めの世界・表のアップロード(最初のフレームで写す。以後は使わない)
391 std::array<ComPtr<ID3D12Resource>, 4> m_reactionTable;
392 // 表 4 つ・セル・キャッシュ(1 世代ぶん。2 世代に写す)・予定の印(初めの起こす刻みの印。ProbeInitialScheduleWords)
393 std::array<ComPtr<ID3D12Resource>, 7> m_initialUploads;
394 bool m_initialized = false;
395 std::array<uint32_t, PROBE_VIEW_SPECIES_COUNT> m_viewSpecies{}; // 抽出に写す物質(O2・CO2・炭)
396 std::array<ComPtr<ID3D12Resource>, PROBE_EXTRACTION_COUNT> m_extractions;
397 ComPtr<ID3D12Resource> m_busySink;
398
399 // --- 物理(T-0098)---
400 std::unique_ptr<GpuPhysics> m_physics;
401 int64_t m_physicsRate = 0; // 物理の 1 秒あたりの小刻みの数(押す力積の計算。フレームの入力の見出しで渡す)
403
404 // --- 刻みの道具(表・キュー・イベント・活性)---
405 ComPtr<ID3D12Resource> m_hashes; // ハッシュの表(PROBE_HASH_BYTES)
406 ComPtr<ID3D12Resource> m_commandQueue; // GPU のコマンドキュー(PROBE_COMMAND_QUEUE_BYTES)
407 ComPtr<ID3D12Resource> m_tickEvents; // 刻みの中のイベントの一時置き場(PROBE_TICK_EVENT_BYTES)
408
409 // 活性の一覧(刻みの偶奇で 2 組。PROBE_ACTIVE_LIST_BYTES)。フレームの中では UAV、伝導の間だけ入力の組を GPU の入力の状態にする
410 std::array<ComPtr<ID3D12Resource>, 2> m_activeLists;
411 ComPtr<ID3D12Resource> m_blockSchedule; // 予定の印(PROBE_SCHEDULE_BYTES)
412
413 // --- 読み戻しとフレームの枠 ---
416 gpu::WorkGraphStats m_graphStats; // 伝導のグラフのノードのカウンタ(T-0008)
417 gpu::GraphTrace m_graphTrace; // 伝導の連鎖のトレース(T-0087)
418 ComPtr<ID3D12QueryHeap> m_timestamps; // slot ごとに MAX_UNITS_PER_FRAME + 2
419 std::array<FrameSlot, FRAME_SLOT_COUNT> m_slots;
420
421 // --- 巻き戻し(T-0143)---
422 std::vector<SavePoint> m_savePoints;
423 ComPtr<ID3D12Resource> m_zeroQueueHeader; // 0 の 16 バイト(戻すときにコマンドキューを空にする)
424
425 // --- GPU のコマンドキューの CPU 側の控え(足すのは CPU だけなので、末尾と待っている数を CPU が知っている)---
426 struct QueuedTick {
427 uint64_t targetTick = 0;
428 uint32_t count = 0;
429 };
430
431 uint32_t m_commandTail = 0; // 足した総数(GPU の末尾と同じ。2^32 で一周)
432 uint32_t m_queuedCommandCount = 0; // まだ適用の単位を記録していないコマンドの数
433 std::vector<QueuedTick> m_queuedTicks; // その内訳(targetTick の昇順)
434 bool m_hasEnqueued = false;
435 ProbeCommand m_lastEnqueued; // 最後に足したコマンド(並びの確認)
436 };
437
438 // --- 初めの世界(T-0089)---
439
440 // 1 世代ぶんのセル(PROBE_CELL_COUNT 個)。全体が 300 K の空気(N2・O2、1 気圧)、中央に木箱
441 // (8³ セル = 4 m 角、壁の厚さ 1 セル、中は空気。壁のセルは体積の 1 割がセルロースで、残りは孔の中の空気)
442 [[nodiscard]] std::vector<reaction::RxCell> MakeProbeInitialWorld(const BakedReactionTable& table);
443
444 // 抽出に写す物質(O2・CO2・炭の順。描画の色分け)
445 [[nodiscard]] std::array<uint32_t, PROBE_VIEW_SPECIES_COUNT> ProbeViewSpecies(const BakedReactionTable& table);
446
447 // --- CPU リファレンス(GPU とビット一致するはずのもの。D-307・CLAUDE.md 原則 4)---
448
449 // 全部のセルを毎刻み計算する(活性を使わない)。GPU は活性のブロックだけを計算するので、一致すれば活性の取り方も正しい
450 // (眠っているブロックは、計算しても変わらないことが規則で決まっている。probe_sim.hlsli の「活性」)。
451 // 予定のブロックの数は、変わった・まだ進めるブロックの記録から GPU と同じ規則で予想する
453 public:
454 // initialWorld が空なら MakeProbeInitialWorld(ProbeSimOptions::initialWorld と同じ)
455 explicit ProbeReference(const BakedReactionTable& table, std::span<const reaction::RxCell> initialWorld = {});
456
457 // 刻み tick を 1 つ進める(targetTick == tick のコマンドを並びの順に適用 → 伝導と反応)。
458 // newTable があれば、刻みの始めに表をそれに差し替える(GPU の ProbeFrameInput::tableSwap と同じ。呼ぶ側が持ち続ける。T-0139)
459 void Advance(uint64_t tick, std::span<const ProbeCommand> commands,
460 const BakedReactionTable* newTable = nullptr);
461
462 // 刻み tick の始めの状態 S(tick)(= tick 回進めた後)
463 [[nodiscard]] std::span<const reaction::RxCell> State(uint64_t tick) const;
464
465 // 同じく、熱のキャッシュ(抽出の温度を作るのに使う)
466 [[nodiscard]] std::span<const reaction::HcThermalCache> Caches(uint64_t tick) const;
467
468 // 最後の Advance のつつきが足したエネルギー(mJ。GPU の表の sourceEnergy と同じ)
469 [[nodiscard]] uint64_t SourceEnergy() const { return m_sourceEnergy; }
470
471 // 最後の Advance で GPU が伝導と反応を計算するはずのブロックの数
472 [[nodiscard]] uint32_t ScheduledBlocks() const { return m_scheduledBlocks; }
473
474 // 最後の Advance で、待ちが来て起きたブロック(前の刻みに計算しなかったのに評価が要る。GPU の WakeDueBlocks が一覧に足す数)
475 [[nodiscard]] uint32_t WokenBlocks() const { return m_wokenBlocks; }
476
477 // 最後の Advance の、ブロックごとの結果(PROBE_BLOCK_COUNT 個の PROBE_BLOCK_FLAG_* の組み合わせ。0 でなければ次の刻みの予定の種。
478 // トレースの予想に使う。sim/probe_trace.h)
479 [[nodiscard]] std::span<const uint8_t> BlockFlags() const { return m_blockFlags; }
480
481 // ブロックごとの最後に変わった刻みの印(tc。PROBE_BLOCK_COUNT 個。次の Advance の評価が使う値。成分と候補の数の分布を
482 // 測る時に読む。T-0163)
483 [[nodiscard]] std::span<const uint64_t> ChangedMarks() const { return m_changedMarks; }
484
485 private:
487 std::vector<reaction::RxCell> m_cells; // 2 世代 × PROBE_CELL_COUNT(GPU と同じ並び)
488 std::vector<reaction::HcThermalCache> m_caches; // 同じ並びの熱のキャッシュ
489 std::vector<uint8_t> m_blockFlags; // 前の刻みのブロックごとの結果(PROBE_BLOCK_COUNT)
490 std::vector<uint64_t> m_changedMarks; // ブロックが最後に変わった刻みの印(tc。待ちの丸め。PROBE_BLOCK_COUNT)
491 std::vector<uint8_t> m_scheduled; // 最後の Advance で予定したブロック(PROBE_BLOCK_COUNT)
492 uint64_t m_sourceEnergy = 0;
493 uint32_t m_scheduledBlocks = 0;
494 uint32_t m_wokenBlocks = 0;
495 };
496
497 // ブロックごとの初めの起こす刻みの印(待ちの丸め。ADR-0018・T-0122): 刻み 0 を tc = 0 で計算してみて、変わるブロックは刻み 0 の印、
498 // 変わらないブロックはセルの次に評価の要る刻みの最小(刻み 0 を計算しなくても同じ結果になる)
499 [[nodiscard]] std::vector<uint64_t> ProbeInitialBlockWakes(const BakedReactionTable& table,
500 std::span<const reaction::RxCell> cells);
501
502 // 予定の印のバッファ(PROBE_SCHEDULE_BYTES)の初めの中身: 予定と tc は 0、起こす刻みは ProbeInitialBlockWakes
503 [[nodiscard]] std::vector<uint32_t> ProbeInitialScheduleWords(const BakedReactionTable& table,
504 std::span<const reaction::RxCell> cells);
505
506 // 状態のハッシュ = Σ ProbeCellHash(セルの番号, セル)(mod 2^64)。GPU のハッシュの単位と同じ値になる
507 [[nodiscard]] uint64_t ProbeStateHash(std::span<const reaction::RxCell> cells);
508
509 // エネルギーの合計(Σ mJ の mod 2^64。GPU の表のエネルギーの合計と同じ値になる)
510 [[nodiscard]] uint64_t ProbeEnergySum(std::span<const reaction::RxCell> cells);
511
512 // 抽出のセルの部分(PROBE_CELL_COUNT × PROBE_EXTRACTION_CELL_WORDS 語: 温度と見る物質 3 つ)を CPU で作る。GPU の Extract と同じ値
513 [[nodiscard]] std::vector<uint32_t> MakeProbeExtractionCells(
514 std::span<const reaction::RxCell> cells, std::span<const reaction::HcThermalCache> caches,
515 const std::array<uint32_t, PROBE_VIEW_SPECIES_COUNT>& viewSpecies);
516
517 // 抽出の語の要約(比べるため。順番に依存する FNV 風の混ぜ方)
518 [[nodiscard]] uint64_t ProbeExtractionHash(std::span<const uint32_t> words);
519
520} // namespace bicameral::sim
std::vector< uint64_t > m_changedMarks
Definition probe_sim.h:490
ProbeReference(const BakedReactionTable &table, std::span< const reaction::RxCell > initialWorld={})
uint64_t SourceEnergy() const
Definition probe_sim.h:469
std::span< const uint8_t > BlockFlags() const
Definition probe_sim.h:479
std::vector< uint8_t > m_blockFlags
Definition probe_sim.h:489
std::span< const reaction::RxCell > State(uint64_t tick) const
std::vector< reaction::RxCell > m_cells
Definition probe_sim.h:487
std::span< const uint64_t > ChangedMarks() const
Definition probe_sim.h:483
const BakedReactionTable * m_table
Definition probe_sim.h:486
std::vector< reaction::HcThermalCache > m_caches
Definition probe_sim.h:488
std::span< const reaction::HcThermalCache > Caches(uint64_t tick) const
void Advance(uint64_t tick, std::span< const ProbeCommand > commands, const BakedReactionTable *newTable=nullptr)
uint32_t ScheduledBlocks() const
Definition probe_sim.h:472
std::vector< uint8_t > m_scheduled
Definition probe_sim.h:491
uint32_t WokenBlocks() const
Definition probe_sim.h:475
void RecordReadbacks(ID3D12GraphicsCommandList10 *list, uint32_t slot, bool hasHash) const
uint32_t BusyUnitCount() const
Definition probe_sim.h:306
ComPtr< ID3D12PipelineState > m_enqueuePipeline
Definition probe_sim.h:372
bool CreateFrameSlots(ID3D12Device5 *device, D3D12_COMMAND_LIST_TYPE listType)
void BindRootViews(ID3D12GraphicsCommandList10 *list, ID3D12Resource *input) const
void RecordExtract(ID3D12GraphicsCommandList10 *list, uint64_t tick, uint32_t target) const
gpu::ReadbackRing m_events
Definition probe_sim.h:414
void WriteInput(FrameSlot &frame, const ProbeFrameInput &input) const
std::expected< void, std::string > CreatePhysics(ID3D12Device5 *device)
ComPtr< ID3D12PipelineState > m_applyPipeline
Definition probe_sim.h:373
std::array< ComPtr< ID3D12Resource >, 2 > m_activeLists
Definition probe_sim.h:410
std::vector< StateRegion > StateRegions(uint64_t tick) const
std::array< ComPtr< ID3D12Resource >, PROBE_EXTRACTION_COUNT > m_extractions
Definition probe_sim.h:396
uint32_t SavePointCount() const
Definition probe_sim.h:260
bool ValidateCommands(const ProbeFrameInput &input) const
ComPtr< ID3D12PipelineState > m_hashCellsPipeline
Definition probe_sim.h:378
bool CreateConductGraph(ID3D12Device5 *device)
ID3D12Resource * Extraction(uint32_t target) const
Definition probe_sim.h:246
void RecordInitialization(ID3D12GraphicsCommandList10 *list)
void DiscardSavePointsAfter(uint64_t tick)
Definition probe_sim.h:266
const gpu::GraphTraceFilter & TraceFilter() const
Definition probe_sim.h:239
uint64_t SavePointBytes() const
ComPtr< ID3D12PipelineState > m_flushEventsPipeline
Definition probe_sim.h:379
std::vector< SavePoint > m_savePoints
Definition probe_sim.h:422
bool CreatePipelines(ID3D12Device5 *device)
void SetTraceFilter(const gpu::GraphTraceFilter &filter)
Definition probe_sim.h:238
ComPtr< ID3D12Resource > m_busySink
Definition probe_sim.h:397
const gpu::GraphStatsLayout & ConductStatsLayout() const
Definition probe_sim.h:242
ComPtr< ID3D12PipelineState > m_refreshTablePipeline
Definition probe_sim.h:376
bool CreateWorld(ID3D12Device5 *device, const BakedReactionTable &table, std::span< const reaction::RxCell > initialWorld)
gpu::DebugRing m_debugRing
Definition probe_sim.h:415
ComPtr< ID3D12Resource > m_zeroQueueHeader
Definition probe_sim.h:423
std::array< FrameSlot, FRAME_SLOT_COUNT > m_slots
Definition probe_sim.h:419
std::array< ComPtr< ID3D12Resource >, 7 > m_initialUploads
Definition probe_sim.h:393
uint32_t PhysicsUnitCount() const
Definition probe_sim.h:307
void TrackCommands(std::span< const ProbeCommand > commands, uint64_t nextApplyTick)
ComPtr< ID3D12PipelineState > m_extractPipeline
Definition probe_sim.h:380
gpu::GraphTrace m_graphTrace
Definition probe_sim.h:417
std::vector< ProbeTickHash > ReadHashes(const FrameSlot &frame) const
bool ValidateInput(uint32_t slot, const ProbeFrameInput &input) const
ComPtr< ID3D12PipelineState > m_busyPipeline
Definition probe_sim.h:377
std::unique_ptr< GpuPhysics > m_physics
Definition probe_sim.h:400
void RecordPhysics(ID3D12GraphicsCommandList10 *list, ID3D12Resource *input, uint64_t tick)
ID3D12Resource * Cells() const
Definition probe_sim.h:249
ComPtr< ID3D12RootSignature > m_rootSignature
Definition probe_sim.h:371
void RecordSave(ID3D12GraphicsCommandList10 *list, uint32_t index, uint64_t tick)
std::vector< QueuedTick > m_queuedTicks
Definition probe_sim.h:433
ComPtr< ID3D12Resource > m_hashes
Definition probe_sim.h:405
uint32_t HashUnit() const
Definition probe_sim.h:218
bool ValidateSavePoints(const ProbeFrameInput &input) const
bool ValidateTableSwap(const ProbeFrameInput &input) const
ComPtr< ID3D12Resource > m_blockSchedule
Definition probe_sim.h:411
uint64_t ConductBackingMemoryBytes() const
Definition probe_sim.h:252
ComPtr< ID3D12QueryHeap > m_timestamps
Definition probe_sim.h:418
std::array< uint32_t, PROBE_VIEW_SPECIES_COUNT > m_viewSpecies
Definition probe_sim.h:395
ProbeCommand m_lastEnqueued
Definition probe_sim.h:435
ComPtr< ID3D12Resource > m_commandQueue
Definition probe_sim.h:406
ProbeSim(const ProbeSimOptions &options, gpu::ReadbackRing &&events, gpu::DebugRing &&debugRing, gpu::WorkGraphStats &&graphStats, gpu::GraphTrace &&graphTrace)
Definition probe_sim.h:298
void RecordExtractAndHook(ID3D12GraphicsCommandList10 *list, uint64_t tick, const ProbeFrameInput &input)
ComPtr< ID3D12Resource > m_tickEvents
Definition probe_sim.h:407
gpu::WorkGraphStats m_graphStats
Definition probe_sim.h:416
bool CreateBuffers(ID3D12Device5 *device)
void RecordActiveListStates(ID3D12GraphicsCommandList10 *list, D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after) const
ComPtr< ID3D12PipelineState > m_wakeDuePipeline
Definition probe_sim.h:374
bool RecordTableSwap(ID3D12GraphicsCommandList10 *list, FrameSlot &frame, const BakedReactionTable &table)
uint32_t UnitsPerTick() const
Definition probe_sim.h:214
ProbeSimOptions m_options
Definition probe_sim.h:368
std::array< ComPtr< ID3D12Resource >, 4 > m_reactionTable
Definition probe_sim.h:391
static constexpr uint32_t MAX_UNITS_PER_FRAME
Definition probe_sim.h:204
static std::expected< ProbeSim, std::string > Create(ID3D12Device5 *device, D3D12_COMMAND_LIST_TYPE listType, const BakedReactionTable &table, const ProbeSimOptions &options={})
uint64_t SavePointTick(uint32_t index) const
Definition probe_sim.h:262
static uint64_t NextApplyTick(uint64_t tick, uint32_t unit)
Definition probe_sim.h:222
const GpuPhysics * Physics() const
Definition probe_sim.h:255
void RecordRestore(ID3D12GraphicsCommandList10 *list, uint32_t index)
void RecordConduct(ID3D12GraphicsCommandList10 *list, ID3D12Resource *input, uint64_t tick)
ComPtr< ID3D12Resource > m_cells
Definition probe_sim.h:388
void RecordEnqueue(ID3D12GraphicsCommandList10 *list, uint32_t commandCount) const
std::unique_ptr< gpu::WorkGraph > m_conductGraph
Definition probe_sim.h:383
void BindRootArguments(ID3D12GraphicsCommandList10 *list, ID3D12Resource *input) const
uint32_t FreeCommandSlots() const
Definition probe_sim.h:227
ProbeFrameReadback ReadFrame(uint32_t slot)
static constexpr uint32_t FRAME_SLOT_COUNT
Definition probe_sim.h:203
ComPtr< ID3D12Resource > m_thermal
Definition probe_sim.h:389
void RecordUnit(ID3D12GraphicsCommandList10 *list, ID3D12Resource *input, uint64_t tick, uint32_t unit, bool tableSwapped)
bool CreateSavePoints(ID3D12Device5 *device, uint32_t count)
ID3D12CommandList * RecordFrame(uint32_t slot, const ProbeFrameInput &input)
void RecordPhysicsInitialization(ID3D12GraphicsCommandList10 *list, ID3D12Resource *input)
constexpr uint32_t NO_SAVE_POINT
Definition probe_sim.h:133
std::vector< uint64_t > ProbeInitialBlockWakes(const BakedReactionTable &table, std::span< const reaction::RxCell > cells)
std::vector< uint32_t > ProbeInitialScheduleWords(const BakedReactionTable &table, std::span< const reaction::RxCell > cells)
uint64_t ProbeStateHash(std::span< const reaction::RxCell > cells)
ProbeCommand MakeTableCommand(uint64_t targetTick, uint32_t sequence, uint64_t version)
std::array< uint32_t, PROBE_VIEW_SPECIES_COUNT > ProbeViewSpecies(const BakedReactionTable &table)
uint64_t TableCommandVersion(const ProbeCommand &command)
Definition probe_sim.h:59
uint64_t ProbeExtractionHash(std::span< const uint32_t > words)
std::vector< uint32_t > MakeProbeExtractionCells(std::span< const reaction::RxCell > cells, std::span< const reaction::HcThermalCache > caches, const std::array< uint32_t, PROBE_VIEW_SPECIES_COUNT > &viewSpecies)
std::vector< reaction::RxCell > MakeProbeInitialWorld(const BakedReactionTable &table)
uint64_t ProbeEnergySum(std::span< const reaction::RxCell > cells)
Command ProbeCommand
Definition probe_sim.h:53
ProbeCommand MakePokeCommand(uint64_t targetTick, uint32_t sequence, uint32_t x, uint32_t y, uint32_t z)
ProbeCommand MakePushCommand(uint64_t targetTick, uint32_t sequence, const std::array< int64_t, 3 > &origin, const std::array< int32_t, 3 > &direction, uint32_t impulseMillinewtonSeconds)
std::array< uint32_t, COMMAND_PAYLOAD_WORDS > payload
Definition command.h:24
uint32_t PokeY() const
Definition probe_sim.h:81
uint32_t PokeZ() const
Definition probe_sim.h:82
friend bool operator==(const ProbeEvent &, const ProbeEvent &)=default
uint32_t PokeX() const
Definition probe_sim.h:80
D3D12_GPU_VIRTUAL_ADDRESS debugRing
Definition probe_sim.h:129
std::function< void(ID3D12GraphicsCommandList10 *list, const ProbeExtractContext &context)> afterExtract
Definition probe_sim.h:162
std::span< const ProbeCommand > commands
Definition probe_sim.h:154
std::span< const ProbeTableSwap > tableSwaps
Definition probe_sim.h:172
std::vector< ProbeTickHash > hashes
Definition probe_sim.h:104
gpu::GraphStatsSnapshot graphStats
Definition probe_sim.h:116
std::vector< gpu::GraphTraceRecord > trace
Definition probe_sim.h:120
std::vector< uint64_t > unitGpuTicks
Definition probe_sim.h:107
std::vector< ProbeEvent > events
Definition probe_sim.h:102
physics::PxParameters physicsParameters
Definition probe_sim.h:193
const PhysicsScene * physicsScene
Definition probe_sim.h:190
std::span< const reaction::RxCell > initialWorld
Definition probe_sim.h:196
GpuPhysicsOptions physicsOptions
Definition probe_sim.h:192
gpu::GraphTraceFilter trace
Definition probe_sim.h:182
std::vector< ComPtr< ID3D12Resource > > keepAlive
Definition probe_sim.h:290
ComPtr< ID3D12Resource > input
Definition probe_sim.h:282
ComPtr< ID3D12CommandAllocator > allocator
Definition probe_sim.h:278
ComPtr< ID3D12Resource > hashReadback
Definition probe_sim.h:287
ComPtr< ID3D12GraphicsCommandList10 > list
Definition probe_sim.h:279
ComPtr< ID3D12Resource > timestampReadback
Definition probe_sim.h:286
std::vector< ComPtr< ID3D12Resource > > buffers
Definition probe_sim.h:357
const BakedReactionTable * table
Definition probe_sim.h:142
uint64_t WorldHash() const
Definition probe_sim.h:97