4 Stimmen

GL/CL-Interoperabilität: Gemeinsame Textur

Ich beabsichtige, mit OpenCL Grafikberechnungen wie Ray Casting, Ray Marching und andere durchzuführen. Und ich möchte OpenGL verwenden, um das Ergebnis dieser Berechnungen (Pixelbilder) anzuzeigen. Ich verwende einen Texturpuffer, der mit dem Framepuffer verbunden ist. OpenCL schreibt das Ergebnis in die Textur und dann verwende ich die Funktion glBlitFrameBuffer, um die Texturdaten in den Framebuffer des Anwendungsfensters zu kopieren. Bei der Implementierung stieß ich auf ein CL/GL-Interproblem. Ich habe ein einfaches Beispiel geschrieben, um es zu zeigen. Dieses Beispiel zeigt die Initialisierung des Framebuffer-Objekts und des Textur-Objekts, ihre Verbindung und die Erstellung des OpenCL-Puffers aus dem GL-Texturpuffer. Am Ende wird die Haupt-Renderschleife gezeigt. Sie besteht aus dem Schreiben der Textur mit neuen Daten in jedem Frame, dem Anhängen des Framebuffers und dem Kopieren des Framebuffers.

Initialisierung der Textur:

for (int i = 0; i < data.Length; i +=4) {
    data [i] = 255;
}
GL.BindTexture (TextureTarget.Texture2D, tboID [0]);
GL.TexImage2D<byte>(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, w, h, 0,
                    PixelFormat.Rgba, PixelType.UnsignedByte, data);
GL.BindTexture (TextureTarget.Texture2D, 0)

TBO+FBO-Initialisierung:

 GL.BindFramebuffer (FramebufferTarget.FramebufferExt, fboID [0]);
 GL.FramebufferTexture2D (FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0,
                          TextureTarget.Texture2D, tboID [0], 0);
 GL.BindFramebuffer (FramebufferTarget.FramebufferExt, 0);

CL/GL-Initialisierung:

bufferID = CL.CreateFromGLTexture2D (context, memInfo, textureTarget, mipLevel, glBufferObject, out errorCode);

Rendering-Schleife:

 for (int i = 0; i < data.Length; i += 4) {
     data [i] = tt;
 }
 tt++;
 GL.BindTexture (TextureTarget.Texture2D, tboID [0]);
 GL.TexImage2D<byte> (TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, w, h, 0,
                      PixelFormat.Rgba, PixelType.UnsignedByte, data);

 GL.BindTexture (TextureTarget.Texture2D, 0);
 GL.BindFramebuffer (FramebufferTarget.FramebufferExt, fboID [0]);
 GL.FramebufferTexture2D (FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0,
                          TextureTarget.Texture2D, tboID [0], 0);
 GL.BindFramebuffer (FramebufferTarget.FramebufferExt, 0);GL.BindFramebuffer (FramebufferTarget.ReadFramebuffer, fboID [0]);

 GL.ReadBuffer (ReadBufferMode.ColorAttachment0);
 GL.DrawBuffer (DrawBufferMode.Back);

 GL.BlitFramebuffer (0, 0, w, h, 0, 0, w, h, ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Nearest);

 GL.BindFramebuffer (FramebufferTarget.ReadFramebuffer, 0);

Auf den ersten Blick sieht dieser Code seltsam aus, aber er zeigt mein Problem vollständig. CL funktioniert hier überhaupt nicht. In dieser Anwendung wird ein OpenCL-Kontext erstellt und eine OpenCL-Pufferinitialisierung durchgeführt. Diese Arbeit sollte einfach sein. Die Farbe des Bildschirms wird von schwarz auf rot geändert. Und so funktioniert es nicht. Die Farbe ändert sich nicht vom anfänglichen Rot (Texturinitialisierung). Aber es funktioniert normal, wenn ich die CL/GL-Initialisierung (Erstellung des CL-Puffers aus der GL-Textur) kommentiere. Warum ist das so? Warum ändert sich das Verhalten des GL-Puffers in Abhängigkeit von CL-Anhängen? Wie kann man das Problem beheben, damit es funktioniert?

3voto

rdoubleui Punkte 3459

EDIT 2:

Dann müssen Sie prüfen, warum Sie eine InvalidImageFormatDescriptor . Prüfen Sie, ob die Reihenfolge der Parameter in Ordnung ist und ob Ihr Bilddeskriptor in der tbo irreführend ist (interne Bildstruktur - siehe OpenCL-Spezifikation). Aus der Spezifikation:

CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, wenn das interne OpenGL-Texturformat nicht einem unterstützten OpenCL-Bildformat entspricht.


EDIT:

Soweit ich weiß, wird die OpenCL-Funktionalität in OpenTK von einem separaten Projekt namens Cloo bereitgestellt. Für ComputeImage2D heißt es in der Dokumentation:

CreateFromGLTexture2D (ComputeContext context, ComputeMemoryFlags flags, int textureTarget, int mipLevel, int textureId)

Verglichen mit Ihrem:

CreateFromGLTexture2D (context, MemFlags.MemReadWrite, TextureTarget.Texture2D, ((uint[])tboID.Clone()) [0], 0);

Sie sehen, dass Sie die Mip-Ebene und die tbo in der falschen Reihenfolge. Eine falsche Initialisierung kann zu einem unbekannten Verhalten führen.


Anhand des Codes, den Sie uns zur Verfügung stellen, ist es schwer zu sagen, was das Problem sein könnte. Bin auf der Suche nach der Interop als auch jetzt, nur immer in sie. Das erste, was ich versuchen würde, ist ein Try/Catch-Block um es zu setzen und versuchen, einen Hinweis auf alle möglichen zu bekommen Fehlercode .

Haben Sie das Offensichtliche überprüft: Ist die cl_khr_gl_sharing Erweiterung auf Ihrem Gerät verfügbar?

Eine andere Vermutung, da Sie nur die Textur-/Bildinitialisierung des eigentlichen OpenCl/OpenGL Interop in Ihrem Beispielcode zur Verfügung gestellt haben: Haben Sie das Speicherobjekt erworben?

cl_int clEnqueueAcquireGLObjects (cl_command_queue command_queue,
  cl_uint num_objects.
  const cl_mem *mem_objects,
  cl_uint num_events_in_wait_list,
  const cl_event *event_wait_list,
  cl_event *event)

En OpenCL 1.1 Spezifikation Staaten:

Die Funktion cl_int clEnqueueAcquireGLObjects wird verwendet, um OpenCL-Speicherobjekte zu erfassen, die aus OpenGL-Objekten erstellt wurden. Diese Objekte müssen erworben werden, bevor sie von OpenCL-Befehlen verwendet werden können, die in der Warteschlange eines Befehlswarteschlange. Die OpenGL-Objekte werden durch den OpenCL-Kontext erworben, der mit command_queue zugeordneten OpenCL-Kontext erworben und können daher von allen mit dem OpenCL Kontext zugeordnet sind.

Das Problem könnte also sein, dass das Speicherobjekt nicht an eine bestimmte Befehlswarteschlange gebunden wurde.

Außerdem ist man verantwortlich für die Ausstellung einer glFinish() um sicherzustellen, dass die gesamte Initialisierung auf der OpenGL-Seite durchgeführt wird, bevor das Speicherobjekt erworben wird.

1voto

Alexander Shukaev Punkte 16026

Schließlich konnten wir Itun' Code auf meinem System (Windows 7 / AMD Radeon HD 5870) ausführen. Erinnern Sie sich, dass der Itun'-Code allmählich die Farbe in Textur von schwarz bis rot mit Hilfe von GL nach Aktivierung von GL/CL Interop auf dieser Textur .

Die Ergebnisse sind zumindest merkwürdig. Auf meinem System funktioniert es wie vorgesehen. Auf Itun' System (Windows 7 / NVidia GeForce) funktioniert derselbe Code jedoch überhaupt nicht und liefert keine Ausnahmen oder Fehlercodes. Darüber hinaus möchte ich erwähnen, dass CL mit dieser Textur auf beiden Systemen ordnungsgemäß funktioniert. Daher ist etwas falsch mit GL in diesem Fall.

Wir haben keine Ahnung, woran es liegt - es könnte entweder Itun' veraltete GPU-Hardware oder fehlerhafte NVidia-Treiber sein.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X