Ich rende einzelne Pixelpunkte in eine uint32-Textur mit einem Compute-Shader. Die Textur ist eine 3D-Textur, x und y sind Ansichtsfenster-Koordinaten, z hat Tiefeninformationen über die Koordinate 0 und zusätzliche Attribute auf 1. also zwei manuell erstellte Renderziele, wenn Sie so wollen. Code sieht wie folgt aus:Manuelles Tiefen-Rendering: Zufällige Ergebnisse trotz atomarer Operationen
layout (r32ui, binding = 0) coherent volatile uniform uimage3D renderBuffer;
layout (rgba32f, binding = 1) restrict readonly uniform imageBuffer pointBuffer;
for(int j = 0; j < numPoints/gl_WorkGroupSize.x + 1; j++)
{
vec4 point = imageLoad(pointBuffer, ...)
// ... transform point ...
uint originalDepth = imageAtomicMin(renderBuffer, ivec3(imageCoords, 0), point.depth);
if (originalDepth >= point.depth)
{
// write happened, store the attributes
imageStore(renderBuffer, ivec3(imageCoords, 1), point.attributes);
}
}
während die Tiefenwerte richtig sind, ich habe ein paar Pixel, bei denen die Attribute zwischen zwei Werten flackern.
Die Reihenfolge der Punkte im PointBuffer ist zufällig (aber ich habe überprüft, die Menge aller Punkte ist immer gleich), so mein erster Gedanke war, dass zwei gleiche Tiefenwerte die Ausgabe ändern können, je nachdem, welche kommt zuerst. also habe ich es so gemacht, dass if originalDepth == point.depth
imageAtomicMax
verwendet, um immer die gleichen der beiden alternativen Attribute geschrieben zu haben, aber das hat nichts verändert.
Ich verstreute und memoryBarrier()
überall, aber das änderte nichts. ich entfernte auch alle divergierenden Kontrollflüsse dafür, änderte nichts.
Wenn Sie die lokale Arbeitsgröße auf 32 reduzieren, werden 90% des Flackerns entfernt, einige bleiben jedoch erhalten.
alle Ideen würden sehr geschätzt werden.
bearbeiten: Bevor Sie fragen, warum ich dieses Zeug manuell anstelle von normalen Rasterisierung und Fragment Shader, der Grund ist Leistung. Der Rasterizer hilft nicht, da ich Single-Pixel-Punkte rendere, Shared Memory beschleunigt Dinge sehr, und ich rendere jeden Punkt mehrere Male, was mich verlangte, einen Geometrie-Shader zu verwenden, der langsam war.
Ich selbst schrieb in einem verdammten Kommentar direkt über diesem BildStore mit der Aussage "mögliche Race Condition hier", aber aus irgendeinem Grund entschied, dass es nicht verantwortlich sein könnte. Wahrscheinlich habe ich mich zu sehr darauf konzentriert ... Egal danke :) Ich rendere in einen Atlas von 64x64 Shadowmaps und habe schon eine Arbeitsgruppe pro SM, aber das ist zu groß, um den Tiefenpuffer im Shared Memory zu haben. Zwei Fragen: Verschiebt die Workgroup-Liste das Problem nicht einfach vom globalen in den gemeinsamen Speicher und ich muss dort auch die Race Condition lösen? Zweitens würde das Pipelining mehrere Dispatch-Aufrufe erfordern, nicht wahr? – karyon
"* verschiebt die pro-workgroup-Liste nicht nur das Problem von globalem zu geteiltem Speicher und ich müsste auch dort die Race-Bedingung lösen? *" Ja, aber es gibt Dinge, die Sie tun können, um es dort zu lösen , die relativ billig sind. –
Ein Zeiger zum Starten wäre nett, da ich am Ende meines Wissens hier bin und dieses Zeug kaum Google-fähig ist ... – karyon