Неявная синхронизация OpenCL / OpenGL на AMD Tahiti

У меня проблема с «неявной синхронизацией» OpenCL и OpenGL на устройстве AMD Tahiti (AMD Radeon HD 7900 Series). Устройство имеет расширения cl / gl, cl_khr_gl_sharing и cl_khr_gl_event.

Когда я запускаю программу, которая представляет собой простое ядро ​​с обновлением vbo, и рисую ее в виде белой линии с простым шейдером, она идиотит как сумасшедшая, останавливая то, что выглядит как 2-4 кадра при каждом обновлении. Я могу подтвердить, что это не ядро ​​cl или шейдер gl, который я использую для обновления и отрисовки буфера, потому что если я добавлю glFinish и commandQueue.finish () до и после получения и выпуска объектов gl для cl обнови, все работает как надо.

Итак, я понял, что мне нужно «включить» расширение события …

#pragma OPENCL EXTENSION cl_khr_gl_event : enable

…в программе cl, но это выдает ошибки. Я предполагаю, что это расширение не относится к клиентскому расширению и должно работать как «ожидаемое», поэтому я не могу включить его.

Третье поведение, которое я заметил … если я возьму glFinish () и commandQueue.finish () и запустю его в отладке CodeXL, неявная синхронизация работает. Например, без каких-либо изменений в кодовой базе, таких как принудительная синхронизация с завершением, CodeXL допускает неявную синхронизацию. Итак, неявная синхронизация четко работает, но я не могу заставить ее работать, просто регулярно запуская приложение через Visual Studio и форсируя синхронизацию.

Я явно что-то упускаю, но, честно говоря, не вижу этого. Буду очень признателен за любые мысли или объяснения, так как я хотел бы сохранить синхронизацию неявной.

3

Решение

Я предполагаю, что вы не используете синхронизацию GLsync-cl_event (GL_ARB_cl_event а также cl_khr_gl_event расширений), поэтому помогает добавление cl / glFinish и служебных данных из CodeXL.

Я думаю, ваш код выглядит так:

A1. clEnqueueNDRangeKernel
A2. clEnqueueReleaseObjects
[here is where you inserted clFinish]
B1. glDraw*
B2. wgl/glXSwapBuffers
[here is where you inserted glFinish]
C1. clEnqueueAcquireObjects
[repeat from A1]

Вместо этого вы должны:

  1. CL-> GL synchro: есть clEnqueueReleaseObjects создать (выходное) событие для передачи glCreateSyncFromCLeventARBзатем используйте glWaitSync (НЕ glClientWaitSync — который в этом случае будет таким же, как clFinish).

  2. GL-> CL synchro: есть clEnqueueAcquireObjects принять (входное) событие, которое будет создано с clCreateFromGLsync, принимая объект синхронизации из glFenceSync

В целом, это должно быть:

A1. `clEnqueueNDRangeKernel`

[Option 1.1:]
A2. `clEnqueueReleaseObjects`( ..., 0, NULL, &eve1)

[Option 1.2:]
A2. `clEnqueueReleaseObjects`( ..., 0, NULL, NULL)
A2'. `clEnqueueMarker`(&eve1)

A3. sync1 = glCreateSyncFromCLeventARB(eve1)
* clReleaseEvent(eve1)
A4. glWaitSync(sync1)
* glDeleteSync(sync1)
B1. glDraw*
B2. wgl/glXSwapBuffers
B3. sync2 = glFenceSync
B4. eve2 = clCreateFromGLSync(sync2)
* glDeleteSync(sync2)

[Option 2.1:]
C1. clEnqueueAcquireObjects(, ..., 1, &eve2, NULL)
* clReleaseEvent(eve2)

[Option 2.2:]
B5. clEnqueueWaitForEvents(1, &eve2)
* clReleaseEvent(eve2)
C1. clEnqueueAcquireObjects(, ..., 0, NULL, NULL)

[Repeat from A1]

(Варианты 1.2 / 2.2 лучше, если вы точно не знаете заранее, какой будет последняя очередь перед передачей управления другому API)

В качестве примечания, я предположил, что вы не используете неупорядоченную очередь для OpenCL (в этом случае действительно не должно быть нужды) — если вы это сделали, вам, конечно же, придется синхронизировать clEnqueueAcquire -> clEnqueueNDRange -> clEnqueueRelease,

1

Другие решения


По вопросам рекламы [email protected]