2016-03-30 10 views
1

Ich versuche, einen OpenCL-Racer zu erstellen. Daher zeichne ich viele Male pro Sekunde auf eine OpenGL-Textur. Jedoch gibt queue.enqueueNDRangeKernel schließlich -9999 zurück. Wenn ich write_imagef aus meinem Kernel-Code entferne, funktioniert es, also dachte ich, dass dies das Problem verursacht.OpenCL - Draw To OpenGL Textur stürzt

OpenCL-Kernel (aufgeschlüsselt)

__kernel void main(__write_only image2d_t screen) 
{ 
    unsigned int x = get_global_id(0); 
    unsigned int y = get_global_id(1); 

    int2 coords = (int2) (x, y); 
    write_imagef(screen, coords, (float4)(1,0,1,1)); 
} 

Dies ist der Code, der einmal in C++ läuft:

cl::Program::Sources sources; 
string code = ResourceLoader::loadFile(filename); 
sources.push_back({ code.c_str(),code.length() }); 

program = cl::Program(OpenCL::context, sources); 

if (program.build({ OpenCL::default_device }) != CL_SUCCESS) 
{ 
    cout << "Could not build program \"" << filename << "\"! Error:" << endl; 
    cout << "OpenCL: Error building: " << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(OpenCL::default_device) << "\n"; 
    system("PAUSE"); 
    exit(1); 
} 
queue = CommandQueue(OpenCL::context, OpenCL::default_device); 
kernel = Kernel(program, "main"); 
//OpenGL texture 
ImageGL b(OpenCL::context, CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0, argument, &error); 

if (error != 0) 
{ 
    cout << "CL Error: " << OpenCL::get_cl_error_string(error) << endl; 
    system("PAUSE"); 
    exit(error); 
} 
kernel.setArg(0, b); 

Dieser Kodex für jeden Rahmen ausgeführt wird:

glFinish(); 
queue.enqueueAcquireGLObjects(&this->buffersGL); 
NDRange range; 
if (lengthZ <= 0 && lengthY <= 0) 
    range = NDRange(lengthX); 
else if (lengthZ <= 0) 
    range = NDRange(lengthX, lengthY); 
else 
    range = NDRange(lengthX, lengthY, lengthZ); 

cl::Event wait; 

cl_int run_err = queue.enqueueNDRangeKernel(kernel, NDRange(), range, NullRange, NULL, &wait); 


if (run_err != 0) 
{ 
    cout << OpenCL::get_cl_error_string(run_err) << " (" << run_err << ")" << endl; 
    system("PAUSE"); 
} 
queue.enqueueReleaseGLObjects(&this->buffersGL); 

Was könnte verursacht den -9999 Fehler und wie kann ich es beheben? Außerdem gibt es oft große Brocken von "toten Pixeln", die in der Textur nicht gezeichnet wurden ...

Antwort

2

Sie fügen die Freigabe von GL-Puffern in die Warteschlange ein, aber warten Sie nicht, bis sie abgeschlossen ist.

queue.enqueueReleaseGLObjects(&this->buffersGL); 

entweder das Ziel Veranstaltung erhält aus diesem (achten Sie auf undichte Stellen!), Oder in der Befehlswarteschlange warten, um alle Aufgaben zu beenden, bevor die Freigabe der GL Objekte fortfahren. Wenn eine Sache in einer Warteschlange von einer anderen abhängt, sollten Sie ihre Bestellung selbst arrangieren.

Sie können auch eine Reihe von Aufgaben in die Warteschlange stellen, die von den GL-Objekten abhängen. Warten Sie entweder darauf, dass sie abgeschlossen werden (beenden Sie die Warteschlange), oder nehmen Sie ihre Ereignisse und füttern Sie sie als Enqueue-Bedingungen an Enqueue-Release-GL-Objekte.

Als beiseite:

weniger Kerne verwenden, kann eine gute Idee sein, statt einer pro Pixel.

0

Die Verwendung von weniger Kernen ist eine gute Idee, anstatt einer pro Pixel.

Vielen Dank Yakk! Ich habe das probiert, indem ich einfach eine kleinere Bildschirmgröße verwendet habe und es hat plötzlich wieder funktioniert! Wie sich herausstellt, war die Textur, zu der ich mich hingezogen hatte, das Problem. Es war nicht 600x600 Pixel groß und das verursachte den Absturz. Scheinbar kann OpenCL zu Pixeln zeichnen, die vor dem Absturz einige Male "nicht existieren". Es ist immer noch seltsames Verhalten ...