Ich versuche , die dritte Übung in Kapitel 12 zu implementieren Einführung in der 3D - Game Programming mit DirectX 11 , das heißt:
- Implementieren Sie einen Compute Shader, um die Länge von 64 Vektoren zu berechnen.
In früheren Übungen wurden Sie gebeten, dasselbe mit typisierten Puffern und regulären strukturierten Puffern zu tun, und ich hatte keine Probleme damit.
Für das, was ich gelesen habe, werden [Consume | Append] StructuredBuffers mithilfe von UnorderedAccessViews an die Pipeline gebunden (sofern sie D3D11_BUFFER_UAV_FLAG_APPEND verwenden und die Puffer sowohl D3D11_BIND_SHADER_RESOURCE als auch D3D11_BIND_UNORDERED_AC haben).
Das Problem ist: Mein AppendStructuredBuffer funktioniert, da ich Daten an ihn anhängen und aus der Anwendung abrufen kann, um in eine Ergebnisdatei zu schreiben, aber der ConsumeStructuredBuffer gibt immer nullte Daten zurück. Daten befinden sich im Puffer, da es funktioniert, wenn ich das UAV in ein ShaderResourceView und in einen StructuredBuffer auf der HLSL-Seite ändere.
Ich weiß nicht, was mir fehlt:
- Sollte ich den ConsumeStructuredBuffer auf der GPU initialisieren oder kann ich dies tun, wenn ich den Puffer erstelle (wie ich es gerade tue)?.
- Ist es in Ordnung, den Puffer wie oben beschrieben mit einem UAV zu binden? Muss ich es irgendwie als ShaderResourceView binden?
- Vielleicht fehlt mir ein Schritt?
Dies ist die Deklaration der Puffer im Compute Shader:
struct Data
{
float3 v;
};
struct Result
{
float l;
};
ConsumeStructuredBuffer<Data> gInput;
AppendStructuredBuffer<Result> gOutput;
Und hier die Erstellung des Puffers und des UAV für Eingabedaten:
D3D11_BUFFER_DESC inputDesc;
inputDesc.Usage = D3D11_USAGE_DEFAULT;
inputDesc.ByteWidth = sizeof(Data) * mNumElements;
inputDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
inputDesc.CPUAccessFlags = 0;
inputDesc.StructureByteStride = sizeof(Data);
inputDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &data[0];
HR(md3dDevice->CreateBuffer(&inputDesc, &vinitData, &mInputBuffer));
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
uavDesc.Format = DXGI_FORMAT_UNKNOWN;
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
uavDesc.Buffer.FirstElement = 0;
uavDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_APPEND;
uavDesc.Buffer.NumElements = mNumElements;
md3dDevice->CreateUnorderedAccessView(mInputBuffer, &uavDesc, &mInputUAV);
Anfangsdaten sind ein Array von Datenstrukturen, die einen XMFLOAT3 mit zufälligen Daten enthalten.
Ich binde das UAV mithilfe des Effekt-Frameworks an den Shader:
ID3DX11EffectUnorderedAccessViewVariable* Input = mFX->GetVariableByName("gInput")->AsUnorderedAccessView();
Input->SetUnorderedAccessView(uav); // uav is mInputUAV
Irgendwelche Ideen?
Vielen Dank.
Ich begann zu glauben, das Problem liege in der Idee, "einen ConsumeStructuredBuffer von der CPU aus zu initialisieren". Da es als Stapel von Elementen "fungiert", ist es sinnvoll, dass die Daten in den Stapel "geschoben" werden müssen, bevor sie "herausspringen".
Also habe ich Folgendes getan: Ich habe einen neuen einfachen Shader erstellt, der einen StructuredBuffer als Eingabe und einen AppendStructuredBuffer als Ausgabe verwendet. Der StructuredBuffer kann von der CPU aus initialisiert werden. Der Shader musste lediglich den AppendStructuredBuffer mit den Daten aus dem StructuredBuffer füllen.
Nun die eigentliche Berechnung: Danach habe ich den oben genannten AppendStructuredBuffer an einen ConsumeStructuredBuffer und den ursprünglichen Ausgabepuffer an eine neue AppendStructuredBuffer HLSL-Variable gebunden.
Und das hat als Charme gewirkt!
Weitere Untersuchungen führten mich zu der Annahme, dass das Vorhandensein des Bindungsflags D3D11_BIND_UNORDERED_ACCESS in einer D3D11_BUFFER_DESC dazu führt, dass die Funktion CreateBuffer alle anfänglichen Daten verwirft: Wenn ich die Shader-Ressourcenansicht (für die Eingabe in den ersten Shader) mit derselben D3D11_BUFFER_DESC wie die ursprüngliche Eingabe Unordered erstellt habe In der Zugriffsansicht wurden keine Daten geladen. Als ich das Bindungsflag D3D11_BIND_UNORDERED_ACCESS entfernte (wobei nur D3D11_BIND_SHADER_RESOURCE übrig blieb), wurden die Daten erfolgreich geladen.
Ich konnte diese "Funktion" jedoch nirgendwo dokumentieren. Kann es jemand bestätigen?
quelle
Benutze das:
kurz vor dem Anwenden der Tech-Pässe in der öffentlichen Funktion DoComputeWork ().
quelle