2016-08-03 9 views
1

Ich benutze DirectX 12, versuche mit UAVs zu rendern. Hier ist mein Pixel-Shader-Code:Warum wird dieser HLSL Pixel Shader nicht kompiliert, wenn RWStructuredBuffer referenziert wird?

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; 
} 

Es Kompilierung schlägt fehl, wenn die D3DCompileFromFile Funktion.

Wenn ich diese Zeile:

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

mit etwas wie folgt aus:

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

, die keinen Hinweis auf die RWStructuredBuffer hat, dann stellt es ganz gut und macht richtig.

Ich glaube nicht, ich habe Probleme mit gebundenen Daten (VS Graphics Debugger zeigt die beiden UAVs ordnungsgemäß gebunden). Ich glaube nicht, dass dies die Erstellung des Shaders beeinflussen würde.

Jedes Mal, wenn ich FLBuffer oder StartOffsetBuffer referenziere, wird es nicht kompilieren.

Was würde dieses Problem verursachen?

Antwort

0

Ich löste das Problem, nachdem ich herausgefunden hatte, wie man den vom Compiler gegebenen Fehler liest. Das Problem hierbei war, dass die Renderzielausgabe das Shader-Register u0 verwendet.

Um dies zu finden, las ich den Fehler nativ von D3DCompileFromFile als ID3DBlob* gegeben, indem es auf eine char* Array konvertieren Sie den Code unten verwenden, wo error eine ist ID3DBlob*:

char* error2; 
int size = error->GetBufferSize(); 
error2 = new char[size/4]; 
error2 = static_cast<char*> (error->GetBufferPointer()); 

Sobald ich die LPVOID umgewandelt Zeiger auf eine char* Array, habe ich einen Haltepunkt unmittelbar nach der letzten Zeile und einfach die Fehlermeldung von der einheimischen Register in VS ausgelesene:

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 

Die Fehlermeldung ist sehr klar und prägnant. Sehr hilfreich.

Der aktualisierte Code:

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; 
} 

Als Hinweis wird der Compiler nicht einmal Code suchen, die nicht auf den return Ausgang beitragen. Ich testete dies, indem ich der Funktion PSMain einen Code hinzufügte, der mit der FLBuffer interagierte, ohne input.color zu beeinflussen, die zurückgegeben wurde. Bei der Demontage wurde der überflüssige Code entfernt und nicht kompiliert.

Getrennt, da ich nicht FLBuffer Referenz habe, wenn es funktioniert, es keine Verbindung zwischen dem Ausgangs-Shader-Register gemacht hat und die u0 Shader melden ich mich gebunden, so ergab sich kein Problem.

Ich muss dann annehmen, dass es überflüssigen Code loswird, bevor er diesen Code überprüft, was sinnvoll ist, wenn man nach Effizienz sucht. Sobald es eine Plausibilitätsprüfung durchführt, wird mit der Kompilierung fortgefahren.

Hoffentlich hilft dies jemand später lernen DirectX oder HLSL.

Verwandte Themen