Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

16.05.2013, 21:31

[D3D11] Computeshader und Vertexbuffers

Hallo ^^,
seit einiger Zeit Interesse ich mich für die Verwendung von Computeshader und wollte mich auch erstmal mit ein einfachen Shader daran wagen.
Was ich erstmal machen wollte, per Computeshader in den Vertexbuffer schreiben. Dafür wollte ich erstmal nur 3 Koordinaten reinschreiben, die zusammen ein Dreieck ergeben, also nicht, was sonderlich kompliziert ist (Shader-Code folgt weiter unten). Die Erstellung der Buffer klappt auch einwandfrei (auch da der Code, weil evt. ja was falsch ist was ich nur einfach übersehe).
Mein Problem ist jetzt nun, wenn ich diesen Buffer als Vertexbuffer in den Context binde, wird leider nichts gerendert. Wenn ich die Daten aber auslese und sie dann in mein Vector speichere, dann bekomme ich auch die richtigen Ergebnisse. Mein Problem ist jetzt nun, wieso auf mein Fenster nichts gerendert wird, wenn ich den Vertexbuffer einsetze. Die Daten darin aber alle korrekt zu scheinen sein.

Allgemeine Infos noch, weil es evt. daran liegen kann, wobei ich mir da aber nicht sicher bin. Mein Device wird mit den Featurelevel 10 erstellt, aber meine Grafikkarte unterstützt Computeshader.

Hier der Code.
Buffer-Erstellung:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Vertexbuffer erstellen
ID3D11Buffer* Vertexbuffer = nullptr;

D3D11_BUFFER_DESC Desc;
ZeroMemory(&Desc, sizeof(Desc));

Desc.ByteWidth = Size;
Desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_VERTEX_BUFFER;
Desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
Desc.Usage = D3D11_USAGE_DEFAULT;
Desc.StructureByteStride = Size / Count; // Size ist die Gesamtgrößse, Count die Anzahl. In diesen Fall also 36 und 3
Desc.CPUAccessFlags = 0;

Device->CreateBuffer(&Desc, nullptr, &Vertexbuffer);

// Acces View erstellen.
D3D11_UNORDERED_ACCESS_VIEW_DESC ViewDesc;
ZeroMemory(&ViewDesc, sizeof(ViewDesc));
ViewDesc.Format = DXGI_FORMAT_R32_TYPELESS;
ViewDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
ViewDesc.Buffer.NumElements = Size / 4;
ViewDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
ViewDesc.Buffer.FirstElement = 0;

Device->CreateUnorderedAccessView(Vertexbuffer, &ViewDesc, &View);


Alles HRESULT werden mit S_OK zurük geben, weshalb da wohl nichts falsch laufen wird(?)

Mein Drawcall sieht so aus

C-/C++-Quelltext

1
2
3
4
5
6
unsigned int Stride = 12;
unsigned int Offset = 0;

DeviceContext->IASetVertexBuffer(0, 1, &Vertexbuffer, &Stride, &Offset);
// Shader setzen, Constantbuffer setzen
DeviceContext->Draw(3, 0);


Hier nochmal mein Shader-Code

HLSL-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[numthreads(1, 1, 1)]
void BuildTriangle(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID,
            uint3 GTid : SV_GroupThreadID)
{

    if(Gid.x == 0)
    {
        float3 Pos = float3(0.0f, 1.0f, 0.0f);
        Data.Store(Gid.x * 12, asuint(Pos.x));
        Data.Store(Gid.x * 12 + 4, asuint(Pos.y));
        Data.Store(Gid.x * 12 + 8, asuint(Pos.z));
    }
    else if(Gid.x == 1)
    {
        float3 Pos = float3(1.0f, -1.0f, 0.0f);
        Data.Store(Gid.x * 12, asuint(Pos.x));
        Data.Store(Gid.x * 12 + 4, asuint(Pos.y));
        Data.Store(Gid.x * 12 + 8, asuint(Pos.z));
    }
    else if(Gid.x == 2)
    {
        float3 Pos = float3(-1.0f, -1.0f, 0.0f);
        Data.Store(Gid.x * 12, asuint(Pos.x));
        Data.Store(Gid.x * 12 + 4, asuint(Pos.y));
        Data.Store(Gid.x * 12 + 8, asuint(Pos.z));
    }
}


Was ich mal Probehalber gemacht habe: einen Vertexbuffer nur mit den D3D11_BIND_VERTEX_BUFFER Flag erstellt und die ausgelesenen Daten in diesen Vertexbuffer reinkopiert. Wenn ich das mache, dann wird auch das Dreieck auf den Bildschirm gerendert. Mit den Debugger bin ich auch schon durchgegangen, und hab nachgeschaut ob die Werte alle richtig sind, was die auch sind. Mich verwundert es nur, wieso es mit den anderen Vertexbuffer nicht klappt. Evt. seht ihr ja, was ich gerade nicht sehe.

Schon mal vielen Dank im voraus.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

16.05.2013, 22:16

Sagt der Direct3D Debug Layer irgendwas? Wofür genau brauchst du D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS? Wofür der StructureByteStride?

3

17.05.2013, 12:30

Stimmt, die StructureByteStride war überflüssig, stammt noch davon, als ich normale StructuredBuffer verwendet habe. Ich hab es mal vorläufig entfernt.
Die Misc-Flag hab ich daher gesetzt, da der Vertexbuffer in Shader ja ein RawByte Buffer ist(?), aber auch ohne diesen Flag der Buffer nicht erstellt werden kann.

Über Direct3D konnte ich noch debuggen, da die Device Erstellung jedesmal fehl schägt, wenn ich das Debug-Flag setze. Woran das liegt, kann ich leider nicht sagen.

4

21.05.2013, 17:28

Sorry für den Doppelpost.
Ich hab übers Wochenende ein bisschen rumprobiert und habe herausgefunden, dass der Buffer funktioniert, wenn man ihn vorab mit Daten füttert und den Computeshader nicht laufen lässt. Was ich aber jetzt komisch finde, dass die Daten von Computeshader zwar in den Buffer geschrieben werden, es aber nicht gerndert wird.

Wegen den Debug Layer. Ich hab versucht mit Hilfe des Control Panels meine .EXE hinzufügen etc. Aber das Device wird dadurch leider immernoch nicht mit dem Debug-Flag erstellt. Eine Beschreibung, wie man das einschaltet hab ich auf der MSDN leider auch nicht gefunden.

Werbeanzeige