2012-01-11 1 views
3

Я собираюсь сделать графический расчет с помощью OpenCL, например, лучевого каста, лучевого марширования и других. И я хочу использовать OpenGL для отображения результата этих вычислений (пиксельных изображений). Я использую буфер текстуры, прикрепленный к буфере кадров. OpenCL записывает результат в текстуру, а затем я использую функцию glBlitFrameBuffer для копирования данных текстуры в фреймбуфер окна приложения. Я столкнулся с проблемой CL/GL inter во время ее реализации. Я написал простой пример, чтобы показать это. В этом примере показан объект framebuffer и инициализация объекта текстуры, их соединение, создание буфера OpenCL из буфера текстуры GL. В конце показан основной цикл рендеринга. Он состоит из записи текстур с новыми данными в каждом кадре, вложением фреймбуфера и копированием этого фреймбуфера.Совместимость с GL/CL: общая текстура

Texture Initialization:

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) 

ТВО + FBO Initialization:

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

CL/GL Initialization:

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

Рендер Loop:

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); 

На первый взгляд этот код выглядит странно, но он полностью показывает мою проблему. CL вообще не работает. В этом приложении создается контекст OpenCL и выполняется инициализация буфера OpenCL. Работа должна быть простой. Цвет экрана меняется с черного на красный. И это не работает таким образом. Цвет не изменяется от начального красного (инициализация текстуры). Но он работает нормально, когда я комментирую инициализацию CL/GL (создание буфера CL из текстуры GL). Почему это так? Почему поведение буфера GL изменяется в зависимости от вложений CL? Как исправить это и заставить его работать?

+0

Я могу в конце концов подтвердить это поведение, как только объект Image2DGL привязан к текстуре, текстура заблокирована и не может быть записана в другой контекст или из другого контекста. Это также устройство nvidia. Возникает вопрос, почему существует явное 'приобретение' и' релиз', если он заблокирован в любом случае. – rdoubleui

ответ

1

Наконец-то мы смогли запустить код Itun в моей системе (Windows 7/AMD Radeon HD 5870). Напомним, что код Itun постепенно меняет цвет в Текстура от черного до красного с помощью GL после активации GL/CL Interop на этой текстуре.

Результаты, по крайней мере, странные. В моей системе это работает по назначению. Однако в системе Itun (Windows 7/NVidia GeForce) тот же код вообще не работает и не содержит никаких исключений или кодов ошибок. Кроме того, я хотел бы упомянуть, что CL работает с этой текстурой должным образом в обеих системах. Поэтому в этом случае что-то не так с GL.

Мы понятия не имеем, что происходит - это может быть устаревшее графическое оборудование Itun или неисправные драйверы NVidia.

+0

Только для записи: Какой чип nVidia у вас есть? – rdoubleui

+0

Кроме того, было бы неплохо узнать, что вам нужно было изменить, чтобы избавиться от этого неправильного дескриптора образа, используя вашу карту amd ... – rdoubleui

3

EDIT 2:

Затем вам нужно проверить, почему вы получаете InvalidImageFormatDescriptor. Убедитесь, что порядок параметров в порядке и недействителен ли дескриптор изображения в tbo (внутренняя структура изображения - см. Спецификацию OpenCL). Из спецификации:

CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, если внутренний формат текстуры OpenGL не сопоставляется с поддерживаемым форматом изображений OpenCL.


EDIT:

Так что я понимаю функциональность OpenCL в OpenTK предоставляется отдельный проект под названием Cloo. Для ComputeImage2D их документации состояний:

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

По сравнению с вашими:

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

Глядя на том, что у вас есть уровень мип и tbo в неправильном порядке. Фальшивая инициализация может привести к некоторому неизвестному поведению.


Трудно сказать, что может быть проблемой из кода, который вы предоставляете. Я тоже сейчас смотрю на Interop, просто попадая в него. Первое, что я хотел бы попробовать, это поставить вокруг него блок try/catch и попытаться понять любую возможную error code.

Проверьте, есть ли у продукта "cl_khr_gl_sharing" на вашем устройстве?

Другое предположение, поскольку вы предоставили только текстуру/Инициализацию изображения фактического OpenCl/OpenGL Interop в вашем примере кода: вы приобрели объект памяти?

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) 

В OpenCL 1.1 specifiction состоянии:

Функция cl_int clEnqueueAcquireGLObjects используется для получения объектов памяти OpenCL, которые были созданы из объектов OpenGL. Эти объекты должны быть приобретены до того, как их можно будет использовать любыми командами OpenCL, стоящими в очереди на командную очередь . Объекты OpenGL приобретаются с помощью контекста OpenCL, связанного с command_queue, и поэтому могут использоваться всеми командами, связанными с контекстом OpenCL .

Таким образом, проблема может заключаться в том, что объект памяти не привязан к определенной командной очереди.

Кроме того, один несет ответственность за выдачу glFinish(), чтобы гарантировать, что вся инициализация на стороне OpenGL выполняется до того, как объект памяти будет получен.

+0

Пример Itun довольно прост - как вы можете видеть, CL там даже не используется - только GL. Поэтому не требуются «clEnqueueAcquireGLObjects» или «glFinish». Суть проблемы заключается в вызове CL.CreateFromGLTexture2D', после чего фрагмент «Render Loop» перестает работать (и снова в примере «Render Loop» используется только GL). Например, в моей системе (Radeon HD 5870) я получаю 'System.Exception: CL Ошибка: InvalidImageFormatDescriptor'. В системе Itun, удивительно (NVidia GeForce ), мы не имеем никакого исключения - GL просто перестает работать должным образом. –

+0

Похоже, если 'CL.CreateFromGLTexture2D' вызовет некоторые помехи. Во всяком случае, многие комбинации (например, с использованием 'glFinish') уже были протестированы. Решение еще впереди. Было бы здорово, если бы кто-то мог протестировать аналогичный код на своих собственных платформах и предоставить некоторую обратную связь. –

+0

Как я уже говорил, я предположил, что не весь код относительно части OpenCL показан (и поэтому не пытался проверить код). OP утверждает, что он хотел выполнять вычисления, такие как лучевое кастинг с OpenCL, поэтому я проверил возможные оставленные выходы в инициализации цепочки взаимодействия CL/GL. – rdoubleui

Смежные вопросы