2

DirectX 12 を使用しており、UAV を使用してレンダリングしようとしています。これが私のピクセルシェーダーコードです:

    struct PSInput
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

struct FragmentDataStruct
{
    float4 color;
    float depth;
};

struct FragmentAndLinkStruct
{
    FragmentDataStruct fragmentData;
    uint nextFragment;
};

RWStructuredBuffer <FragmentAndLinkStruct> FLBuffer : register(u0);

RWByteAddressBuffer StartOffsetBuffer : register(u1);

float4 PSMain(PSInput input) : SV_TARGET
{
    input.color.x = float(FLBuffer[0].nextFragment);

    return input.color;
}

関数を使用するとコンパイルに失敗しD3DCompileFromFileます。

この行を置き換えると:

input.color.x = float(FLBuffer[0].nextFragment);

このようなもので:

FragmentAndLinkStruct otherThing;
otherThing.nextFragment = 1;
input.color.x = float(otherThing.nextFragment);

について言及されていないRWStructuredBuffer場合、問題なくコンパイルされ、適切にレンダリングされます。

バインドされたデータに問題はないと思います (VS Graphics Debugger は、適切にバインドされた 2 つの UAV を示しています)。ただし、それがシェーダーのコンパイルに影響を与えるとは思いません。

FLBufferまたはを参照するたびにStartOffsetBuffer、コンパイルされません。

この問題の原因は何ですか?

4

1 に答える 1

0

コンパイラから出されたエラーの読み方がわかったので、問題を解決しました。ここでの問題は、レンダー ターゲットの出力がu0シェーダー レジスタを使用することでした。

これを見つけるために、以下のコードを使用して配列に変換することにより、D3DCompileFromFileからネイティブに与えられたエラーを読み取ります。ここで、 は です。ID3DBlob*char*errorID3DBlob*

const char* error2 = static_cast<const char*>(error->GetBufferPointer());

最後の行の直後にブレークポイントを設定し、VS の [ローカル] タブからエラー メッセージを読み上げるだけです。

error X4509: UAV registers live in the same name space as outputs, so they
must be bound to at least u1, manual bind to slot u0 failed

エラーメッセージは非常に明確で簡潔です。非常に役立ちます。

更新されたコード:

struct PSInput
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

struct FragmentDataStruct
{
    float4 color;
    float depth;
};

struct FragmentAndLinkStruct
{
    FragmentDataStruct fragmentData;
    uint nextFragment;
};

RWStructuredBuffer <FragmentAndLinkStruct> FLBuffer : register(u1);

RWByteAddressBuffer StartOffsetBuffer : register(u2);

float4 PSMain(PSInput input) : SV_TARGET
{
    uint pixelCount = FLBuffer.IncrementCounter();
    input.color.x = float(pixelCount);

    return input.color;
}

return注意として、コンパイラは、出力に寄与しないコードを調べません。返されるに影響を与えずにPSMainとやり取りするコードを関数に追加して、これをテストしました。逆アセンブルを見ると、余分なコードはすべて削除され、コンパイルされていません。FLBufferinput.color

それとは別に、動作時に参照FLBufferしなかったため、出力シェーダー レジスタとu0バインドしたシェーダー レジスタの間に接続が行われなかったので、問題は発生しませんでした。

次に、そのコードの健全性をチェックする前に余分なコードを取り除くと仮定する必要があります。これは、効率を求める場合に理にかなっています。健全性チェックが完了すると、コンパイルに進みます。

これが後で DirectX や HLSL を学習するのに役立つことを願っています。

于 2016-08-03T04:44:57.150 に答える