Bicameral Engine
GPU-resident engine for a magic-research open-world game
Loading...
Searching...
No Matches
gpu_multires_implicit.h
Go to the documentation of this file.
1// gpu_multires_implicit.h — GPU の伝導の段から細かいレベルの熱の陰解法(方式②。ADR-0019・D-434 案 a)を呼ぶ(T-0132)。
2// CPU リファレンスは multires_implicit_conduction.cpp の AddImplicitConduction(StepConduction の最後の小刻みの流れの後)。
3// データの流れ(1 刻み。GpuMultires::RecordConduction が流れの段の後・ConductApply の前に Record を呼ぶ):
4// GpuMultires の木(流れの後。凍った印つき)→ GpuImplicitBuild(未知数・境のセル・面・セルの面の一覧)→ GpuImplicitLevels(多重格子の段)
5// → GpuImplicit(写して 1 刻み解く)→ GpuImplicitBuild::RecordApply(解いた変化を伝導の変化の表へ。活性なら伝導の一覧へ)→ ConductApply が足す
6// CPU は系の大きさも段の数も知らない(大きさは上限から。T-0136)。記録の形(GpuImplicitRecordShape)は前の刻みの数から選ぶ(T-0154。
7// 数は遅れて読んだものでよい: 形は費用だけを変え、解いた値は同じ)。
8// 使い方: multires->EnableImplicitConduction(device, limits) の後、MultiresStepOptions::implicitConduction の刻みを RecordStep・RecordStepActive で。
9// 上限(GpuMultiresImplicitLimits = MultiresImplicitLimits。T-0178): 流れの段の前に RecordAdmit が、系に入れるブロックを枠の順に予算
10// (MakeMultiresImplicitBudget)の中まで選ぶ。入らないブロックはその刻み陽解法のまま(Q22 の案 A。仮)。多重格子の 2 段目からが上限に
11// 入らなければ縮約を止める。CPU と比べる時は options.implicitLimits に同じ上限を入れる(CPU の MarkImplicitBlocks・BuildImplicitGrid)。
12#pragma once
13
14#include <cstdint>
15#include <expected>
16#include <string>
17
18#include "sim/gpu_implicit.h"
21
22namespace bicameral::sim {
23
25 public:
26 [[nodiscard]] static std::expected<GpuMultiresImplicit, std::string> Create(
27 ID3D12Device5* device, const GpuMultires& multires, const MultiresCapacity& capacity,
28 const GpuMultiresImplicitLimits& limits);
29
30 // 系に入れるブロックを選んで陰解法の印を付ける(T-0178。GpuMultires の伝導の段の流れの前。頁と端数の枠を配った後)
31 void RecordAdmit(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, GpuMultires& multires,
32 const MultiresStepOptions& options);
33
34 // 1 刻みの陰解法(GpuMultires の伝導の段から。RecordAdmit の後。刻みの印と stepFlags は multires に置いたまま)
35 void Record(ID3D12GraphicsCommandList10* list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, GpuMultires& multires,
36 const MultiresStepOptions& options);
37
38 // 計測用: true なら Record が段の境に multires のタイムスタンプを打つ(PHASE_STAMP_FIRST から順に: 系を作る前・段の前・解く前・
39 // 足す前・足した後。読むのは multires.ReadTimestamps)
40 void StampPhases(bool stamp) { m_stampPhases = stamp; }
41 static constexpr uint32_t PHASE_STAMP_FIRST = 2;
42 static constexpr uint32_t PHASE_STAMP_COUNT = 5;
43
44 // 最後に読み戻せた刻みの数(V の回数・安全網・段の形。リストの実行が終わった後に読むとその刻みの値)
45 [[nodiscard]] bool ReadCost(GpuImplicitCost& cost) const { return m_implicit.ReadCost(cost); }
46
47 private:
49 : m_build(std::move(build)), m_levels(std::move(levels)), m_implicit(std::move(implicit)) {}
50
54 bool m_recorded = false; // 一度でも記録したか(前の刻みの数があるか)
55 bool m_stampPhases = false;
56 };
57
58} // namespace bicameral::sim
void RecordAdmit(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, GpuMultires &multires, const MultiresStepOptions &options)
static constexpr uint32_t PHASE_STAMP_FIRST
static std::expected< GpuMultiresImplicit, std::string > Create(ID3D12Device5 *device, const GpuMultires &multires, const MultiresCapacity &capacity, const GpuMultiresImplicitLimits &limits)
GpuMultiresImplicit(GpuImplicitBuild build, GpuImplicitLevels levels, GpuImplicit implicit)
void Record(ID3D12GraphicsCommandList10 *list, D3D12_GPU_VIRTUAL_ADDRESS debugRing, GpuMultires &multires, const MultiresStepOptions &options)
static constexpr uint32_t PHASE_STAMP_COUNT
bool ReadCost(GpuImplicitCost &cost) const
MultiresImplicitLimits GpuMultiresImplicitLimits