Ich habe versucht, einen allgemeinen Compute Shader Gaussian Blur Implementierung zu schreiben.Compute Shader Shared Memory enthält Artefakte
Es funktioniert im Grunde, aber es enthält Artefakte, die jedes Bild ändern, selbst wenn die Szene statisch ist. Ich habe die letzten paar Stunden damit verbracht, das zu debuggen. Ich bin so weit gegangen, die Grenzen nicht zu überschreiten, alle Schleifen abzurollen, Uniformen durch Konstanten zu ersetzen, aber die Artefakte bleiben bestehen.
Ich habe den ursprünglichen Code mit Artefakten auf 3 verschiedenen Maschinen/GPUs (2 nvidia, 1 Intel) getestet und sie alle produzieren die gleichen Ergebnisse. Das Simulieren der entrollten/konstanten Version der Codeausführung mit Arbeitsgruppen, die mit reinem C++ - Code vorwärts und rückwärts ausgeführt werden, erzeugt diese Fehler nicht.
Durch eine gemeinsame Anordnung von [96] [96] anstelle von [16] [48] Zuteilen kann ich die meisten Artefakte vermeiden.
Das brachte mich dazu, zu denken, dass mir ein logischer Fehler fehlte, daher gelang es mir, einen sehr einfachen Shader zu erzeugen, der den Fehler in kleinerem Maßstab erzeugt. Ich würde es schätzen, wenn jemand die Ursache aufzeigen könnte . Ich habe viele Unterlagen überprüft und kann nichts falsch finden.
Ein gemeinsam genutztes Array von 16x48 Floats wird zugewiesen, das sind 3072 Byte, ungefähr 10% des minimalen gemeinsamen Speicherlimits.
Der Shader in 16x16 Arbeitsgruppen gestartet wird, so dass jeder Faden wird auf 3 einzigartige Stellen schreiben und lesen zurück von einer einzigen einzigartigen Lage
Die Textur wird dann als HSV Renderer wobei vals zwischen 0-1 wird abzubilden Farbton 0-360 (rot-cyan-rot), und Werte außerhalb der Grenzen sind rot.
#version 430
//Execute in 16x16 sized thread blocks
layout(local_size_x=16,local_size_y=16) in;
uniform layout (r32f) restrict writeonly image2D _imageOut;
shared float hoz[16][48];
void main()
{
//Init shared memory with a big out of bounds value we can identify
hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y] = 20000.0f;
hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+16] = 20000.0f;
hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+32] = 20000.0f;
//Sync shared memory
memoryBarrierShared();
//Write the values we want to actually read back
hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y] = 0.5f;
hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+16] = 0.5f;
hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+32] = 0.5f;
//Sync shared memory
memoryBarrierShared();
//i=0,8,16 work
//i=1-7,9-5,17 don't work (haven't bothered testing further
const int i = 17;
imageStore(_imageOut, ivec2(gl_GlobalInvocationID.xy), vec4(hoz[gl_LocalInvocationID.x][gl_LocalInvocationID.y+i]));
//Sync shared memory (can't hurt)
memoryBarrierShared();
}
Das Starten dieses Shaders mit Startabmessungen größer als 8x8 führt zu Artefakten im betroffenen Bereich des Bildes.
glDispatchCompute(9, 9, 0); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
Ich musste Frames Breakpoint und Schritt, dies zu erfassen, nahm um 14 Frames
glDispatchCompute(512/16, 512/16, 0);//Full image is 512x512 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
Wieder musste ich Stopp-und Schritt Rahmen dieses zu erfassen, Beim Ausführen mit 60FPS (vsync) erschienen Artefakte häufiger/gleichzeitig.
Danke, das ist es behoben. Nochmals skimming docs zu schnell. – Robadob