Bicameral Engine
GPU-resident engine for a magic-research open-world game
Loading...
Searching...
No Matches
probe_peek.h
Go to the documentation of this file.
1// probe_peek.h — 覗き窓(T-0096。17 §3 B「見るだけなら変わらない」): 仮の世界(sim/probe_sim の 64³)の 1 点の周りを
2// 観察の影の鎖(k = 1〜9、0.5 m → 約 1 mm)にして、デバッグ表示が読む抽出の覗きの欄へ写す。
3//
4// データの流れ(ProbeSim の抽出の後のフック。ProbeFrameInput::afterExtract):
5// 世界のセル S(t) の、点を含む 8³ のブロック → 入れ子の枠 0(世界の写し MR_BLOCK_MIRROR。毎回写し直す)
6// → 初めてなら細かくする(影の鎖 = 枠 1〜9、shaders/sim/multires_graph.hlsl)
7// それ以外は、世界の刻みが進んでいれば影を 1 刻み(multires_step.hlsl)→ 親へ引き戻す(上から順に)
8// → 影のセルの温度と見る物質の量を抽出の覗きの欄へ(shaders/sim/multires_peek.hlsl。並びは probe_sim.hlsli)
9// 世界のバッファは読むだけなので、覗いても世界のハッシュ列は変わらない(window_replay_peek の ctest が確かめる)。
10// 影の時間: 抽出は 1 フレームに 1 回までなので、世界が 1 フレームに何刻み進んでも影は 1 刻み(器具の中の時間はゆっくりでよい。17 §4)。
11//
12// 覗く場所は CPU が決める View の状態(D-107 の Controller。世界には入らない)。CPU リファレンスは ProbePeekReference(同じ順・同じ関数)。
13// 浮動小数点は使わない(engine/src/sim は検査の対象)。
14#pragma once
15
16#include <array>
17#include <cstdint>
18#include <expected>
19#include <span>
20#include <string>
21#include <vector>
22
23#include "common/probe_sim.hlsli"
24#include "sim/gpu_multires.h"
25#include "sim/multires_nest.h"
26#include "sim/probe_sim.h"
27#include "sim/reaction_table.h"
28
29namespace bicameral::sim {
30
31 // --- 入れ子の枠(shaders/sim/multires_peek.hlsl の PEEK_MIRROR_SLOT と同じ)---
32 inline constexpr uint32_t PEEK_MIRROR_SLOT = 0;
33 inline constexpr uint32_t PEEK_FIRST_SHADOW_SLOT = 1;
34 inline constexpr uint32_t PEEK_LEVEL_COUNT = PROBE_PEEK_MAX_LEVELS;
36 static_assert(PROBE_PEEK_BLOCK_CELLS == multires::MR_BLOCK_CELLS &&
37 PROBE_PEEK_BLOCK_EDGE == multires::MR_BLOCK_EDGE);
38
39 // 覗く世界のセル
40 struct PeekCell {
41 uint32_t x = 0;
42 uint32_t y = 0;
43 uint32_t z = 0;
44
45 bool operator==(const PeekCell&) const = default;
46 };
47
48 // 覗く点(一番細かいレベルのセルの単位): 世界のセルの真ん中
49 [[nodiscard]] MultiresPoint PeekPointOfCell(PeekCell cell);
50
51 // 覗く場所の状態(GPU と CPU リファレンスで共通。どの順で何を記録するかを決める)
52 class PeekState {
53 public:
54 void Look(PeekCell cell) {
55 m_requested = cell;
56 m_hasRequest = true;
57 }
58
59 void Stop() { m_hasRequest = false; }
60
61 [[nodiscard]] bool IsLooking() const { return m_hasRequest; }
62 [[nodiscard]] PeekCell Requested() const { return m_requested; }
63
64 // 1 回の抽出で何をするか(Plan を呼ぶと、その結果を記録した前提で状態が進む)
65 struct Plan {
66 bool removeShadow = false; // 前の影の鎖を捨てる
67 bool mirror = false; // 世界の写しを写し直す
68 bool refine = false; // 影の鎖を作る
69 bool step = false; // 影を 1 刻み
70 bool pullBack = false; // 親へ引き戻す
71 PeekCell cell; // 覗いているセル(mirror のとき)
72 };
73
74 [[nodiscard]] Plan NextPlan(uint64_t tick);
75
76 private:
78 bool m_hasRequest = false;
79
80 // --- 影の鎖の今 ---
82 bool m_hasActive = false;
83 uint64_t m_lastTick = 0; // 影が最後に追いついた世界の刻み
84 };
85
86 // --- GPU ---
87 class ProbePeek {
88 public:
89 [[nodiscard]] static std::expected<ProbePeek, std::string> Create(ID3D12Device5* device,
90 const BakedReactionTable& table);
91
92 void Look(PeekCell cell) { m_state.Look(cell); }
93 void Stop() { m_state.Stop(); }
94 [[nodiscard]] bool IsLooking() const { return m_state.IsLooking(); }
95 [[nodiscard]] PeekCell Requested() const { return m_state.Requested(); }
96
97 // ProbeFrameInput::afterExtract から呼ぶ(シミュのフレームのリストの抽出の後ろ)
98 void RecordAfterExtract(ID3D12GraphicsCommandList10* list, const ProbeExtractContext& context);
99
100 // テスト: 入れ子(見出し・セル・端数・数える欄)を読み戻す
101 void RecordReadback(ID3D12GraphicsCommandList10* list) { m_nest.RecordReadback(list); }
102 [[nodiscard]] bool Read(MultiresNest& nest) const { return m_nest.Read(nest); }
103
104 private:
105 ProbePeek(GpuMultires&& nest, const std::array<uint32_t, PROBE_VIEW_SPECIES_COUNT>& viewSpecies)
106 : m_nest(std::move(nest)), m_viewSpecies(viewSpecies) {}
107
109 ComPtr<ID3D12PipelineState> m_mirrorPipeline;
110 ComPtr<ID3D12PipelineState> m_extractPipeline;
111 std::array<uint32_t, PROBE_VIEW_SPECIES_COUNT> m_viewSpecies{};
113 bool m_uploaded = false; // 空の入れ子を写したか(最初のフックで 1 回)
114 };
115
116 // --- CPU リファレンス(ProbePeek とビット一致するはずのもの。CLAUDE.md 原則 4)---
118 public:
119 explicit ProbePeekReference(const BakedReactionTable& table);
120
121 void Look(PeekCell cell) { m_state.Look(cell); }
122 void Stop() { m_state.Stop(); }
123
124 // 抽出 1 回ぶん。world は S(tick) の 1 世代(PROBE_CELL_COUNT 個)
125 void Advance(std::span<const reaction::RxCell> world, uint64_t tick);
126
127 [[nodiscard]] const MultiresNest& Nest() const { return m_nest; }
128
129 // 抽出の覗きの欄(PROBE_EXTRACTION_PEEK_WORDS 語。GPU の ExtractShadow と同じ値。書かない語は 0)
130 [[nodiscard]] std::vector<uint32_t> Extraction() const;
131
132 private:
134 std::array<uint32_t, PROBE_VIEW_SPECIES_COUNT> m_viewSpecies{};
137 };
138
139} // namespace bicameral::sim
void Look(PeekCell cell)
Definition probe_peek.h:54
Plan NextPlan(uint64_t tick)
PeekCell Requested() const
Definition probe_peek.h:62
std::vector< uint32_t > Extraction() const
const BakedReactionTable * m_table
Definition probe_peek.h:133
const MultiresNest & Nest() const
Definition probe_peek.h:127
std::array< uint32_t, PROBE_VIEW_SPECIES_COUNT > m_viewSpecies
Definition probe_peek.h:134
void Advance(std::span< const reaction::RxCell > world, uint64_t tick)
ProbePeekReference(const BakedReactionTable &table)
static std::expected< ProbePeek, std::string > Create(ID3D12Device5 *device, const BakedReactionTable &table)
void RecordReadback(ID3D12GraphicsCommandList10 *list)
Definition probe_peek.h:101
ComPtr< ID3D12PipelineState > m_extractPipeline
Definition probe_peek.h:110
ProbePeek(GpuMultires &&nest, const std::array< uint32_t, PROBE_VIEW_SPECIES_COUNT > &viewSpecies)
Definition probe_peek.h:105
bool Read(MultiresNest &nest) const
Definition probe_peek.h:102
ComPtr< ID3D12PipelineState > m_mirrorPipeline
Definition probe_peek.h:109
void RecordAfterExtract(ID3D12GraphicsCommandList10 *list, const ProbeExtractContext &context)
std::array< uint32_t, PROBE_VIEW_SPECIES_COUNT > m_viewSpecies
Definition probe_peek.h:111
PeekCell Requested() const
Definition probe_peek.h:95
void Look(PeekCell cell)
Definition probe_peek.h:92
MultiresPoint PeekPointOfCell(PeekCell cell)
constexpr uint32_t PEEK_LEVEL_COUNT
Definition probe_peek.h:34
constexpr uint32_t PEEK_FIRST_SHADOW_SLOT
Definition probe_peek.h:33
constexpr uint32_t PEEK_MIRROR_SLOT
Definition probe_peek.h:32
constexpr uint32_t PEEK_BLOCK_CAPACITY
Definition probe_peek.h:35
bool operator==(const PeekCell &) const =default