### 領域 シェーダーのHLSLへの変換 ### パッケージの版数 ComputeWeave 2.6.0(既定ブランチの `a8245449`、v2.6.0 のタグと同じ木)の生成器に PR #243 の枝(`5cce9d1f`)を重ねた木で測りました。静的構築子は既定ブランチでも取り込まれないので、同じです。 ### 診断ID 無し。 ### 期待した挙動 静的構築子が値を入れる静的フィールドを取り込む形は、断られること。C# はその型が最初に触れられたときに静的構築子を走らせて値を入れますが、生成HLSLには静的構築子が無く、フィールドは初期化子を持たない静的変数として書き出されます。 ### 実際の挙動 診断なく通り、生成HLSLは零を計算します。 | 形 | 診断 | C# | 生成HLSL | | --- | --- | --- | --- | | `readonly` の静的フィールドへ静的構築子が 5 を書き、本文が読む | 無し | 5 | 0 | | 可変の静的フィールドへ静的構築子が 5 を書き、本文が読む | 無し | 5 | 0 | C# の列はコンソールで走らせて読み、生成HLSLの列は生成物と同じ形の手書きの HLSL を同梱の DXC(1.7.2308.7)と SDK 10.0.26100.0 の FXC へ当てて格納される値を読みました。`static const float V;` のように初期化子を持たない定数も、どちらのコンパイラも断らずに 0 として通します。実機では読んでいません。 ### 再現手順 ```csharp using ComputeWeave; namespace Shaders; internal static class H { public static readonly float V; static H() { V = 5.0f; } } [ThreadGroupSize(DefaultThreadGroupSizes.X)] [GeneratedComputeShaderDescriptor] internal readonly partial struct Shader : IComputeShader { private readonly ReadWriteBuffer<float> buffer; public void Execute() { this.buffer[0] = H.V; } } ``` 生成HLSLは `static const float Shaders_H_V;` で、`V` は 0 です。`V` を `public static float V;` にしても `static float Shaders_H_V;` で 0 です。 ### 切り分け 生成器は静的フィールドの初期化子だけを写し、静的構築子の本体は読みません。初期化子を持たないフィールドは、C# では既定値のままか静的構築子が値を入れるかのどちらかで、後者を見分ける材料は宣言している型に静的構築子が在るかどうかです。 ### 何を保証すべきか 生成HLSLに静的構築子は写せないので、静的構築子を持つ型から、初期化子を持たない静的フィールドを取り込む形は断るのが筋です。初期化子を持つフィールドも、静的構築子がそれを書き換える形なら同じです。断る位置は、そのフィールドを読む側です。 ### 測っていないこと 実機の値。Direct2D 側。静的構築子が初期化子を持つフィールドを書き換える形。 ### デバイス 統合GPU ### アダプターとドライバー Intel(R) Iris(R) Xe Graphics, 32.0.101.7085 ### Windowsの版数 Windows 11 Pro 24H2, 26200 ### .NET SDKの版数 10.0.400 ### デバッグレイヤーの出力 _No response_ ### その他 PR #243 の自己再評価で、初期化子を持たないフィールドの扱いを測る中で見つけました。同じ型の中の順序(課題 #239、#240、#245)とは別の族なので、別の課題にします。 ### 提出の前に - [x] 最新の公開版を使っています。 - [x] 既存の課題を検索し、重複でないことを確認しました。 - [x] 独自の ID3D12MemoryAllocator を設定していないことを確認しました。
Activity