Repository navigation
[Bug] 限定子を落として書き出すシェーダーのメンバーが、同じ名前の局所変数や引数に生成HLSLで隠される #256
Description
領域
シェーダーのHLSLへの変換
パッケージの版数
ComputeWeave 2.6.0(測ったのは #252 の枝の先端 7508bed3 で、既定ブランチ c050699d に #252 の変更を載せたものです。フィールドの3形は #252 の変更の外です)
診断ID
無し。フィールドの3形は診断なく建ち、装置で C# と違う値を計算します。メソッドの3形は生成物の行を名指す CMPW0046 です。
期待した挙動
this.amount や Shader.Factor のように限定子を付けて読んだメンバーが、同じ名前の局所変数や引数が在っても C# と同じくそのメンバーを指すこと。指せないなら、著者の書いた位置を名指して断ること。
実際の挙動
生成器は限定子を落として名前だけを書き出します。this. はフィールドの読みから落とし、型名は静的フィールドの読み(#182)と静的メソッドの呼び出し(#252)から落とします。HLSL は名前だけで解決するので、同じ名前の局所変数や引数がその名前を隠し、C# ではメンバーを指していた読みが局所変数を指します。
生成器へ直接通した6形と対照3形、装置で読み戻した3形です。
| 書いた形 | 生成HLSL | 装置の値(C# の値) |
|---|---|---|
float amount = 3.0f; x = this.amount;(捕捉したフィールドは 10) |
float amount = 3.0; x = amount; |
3(10) |
float Factor = 3.0f; x = Shader.Factor;(静的フィールドは 2) |
float Factor = 3.0; x = Factor; |
3(2) |
float Go(float amount) => this.amount + amount; を Go(1.0f)(捕捉したフィールドは 10) |
return amount + amount; |
2(11) |
float Twice = 1.0f; x = Shader.Twice() + Twice; |
float Twice = 1.0; x = Twice() + Twice; |
建たない。CMPW0046 |
float Go(float Twice) => Shader.Twice() + Twice; |
return Twice() + Twice; |
建たない。CMPW0046 |
float Twice = 1.0f; x = this.Twice() + Twice; |
float Twice = 1.0; x = Twice() + Twice; |
建たない。CMPW0046 |
対照。定数は __Shaders_Shader__Scale の名前で書き出されるので隠れません。局所関数は __Execute__Twice へ改名されるので、同じ名前の静的メソッドと衝突しません。
再現手順
using ComputeWeave;
namespace Shaders;
[AutoConstructor]
[ThreadGroupSize(DefaultThreadGroupSizes.X)]
[GeneratedComputeShaderDescriptor]
internal readonly partial struct Shader : IComputeShader
{
public readonly ReadWriteBuffer<float> buffer;
public readonly float amount;
public void Execute()
{
float amount = 3.0f;
buffer[0] = this.amount;
}
}new Shader(buffer, 10.0f) を派遣すると buffer[0] は 3 になります。
切り分け
限定子を落とす箇所は3種です。this. を落とすフィールドの読み、型名を落とす静的フィールドの読み、型名と this を落とすメソッドの呼び出しです。落とした名前がその位置で局所変数や引数に解決されるかどうかは、どの箇所も見ていません。C# では限定子が名前解決を決めるので、同じ関数の中で amount と this.amount は別の記号を指せますが、HLSL は名前だけで解決します。
何を保証すべきか
限定子を落とした名前が、その位置で局所変数か引数に解決されるなら、著者の書いた位置を名指して断ること。断る箇所は限定子を落とす3種の箇所で、その位置に同じ名前の局所か引数が見えるかを意味解析で引けば足ります。値が黙って変わる3形と、建たない3形を同じ診断で断てます。
測っていないこと
Direct2D 側は測っていません。書き換え器は共有なので同じ形になると読んでいます。
デバイス
他は試していない
アダプターとドライバー
Intel(R) Iris(R) Xe Graphics, 32.0.101.7085
Windowsの版数
Windows 11 Pro 24H2, 26200
.NET SDKの版数
10.0.400
デバッグレイヤーの出力
No response
その他
#252 の自己再評価で見つけました。#252 は限定子を落とす形をメソッドの呼び出しの分だけ増やしますが、メソッドの3形は #252 の前は限定子が残って CMPW0046 になり、後も CMPW0046 になるので、#252 で悪くなった形はありません。フィールドの3形は #252 の前から同じです。
提出の前に
- 最新の公開版を使っています。
- 既存の課題を検索し、重複でないことを確認しました。
- 独自の ID3D12MemoryAllocator を設定していないことを確認しました。
Activity
routersys commentedon Sep 17, 2026
フィールドの読みの3形は #263 で
CMPW0131(Direct2D側はCMPWD2D0104)として断ちました。見るのは、生成HLSLがその関数の中でその読みより前に宣言する局所変数と引数だけで、引数の中の宣言は本体の先頭へ持ち上げられるので位置を問わず、あとで宣言された局所変数と囲む関数の局所変数は隠さないので断ちません。メソッドの呼び出しの3形は、限定子を落とす箇所そのものが #252 で入るので、#252 が入ったあとに同じ報告をその箇所へ足します。この課題はそれまで開けておきます。