Russian Qt Forum
Ноябрь 23, 2024, 00:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: OpenGL+Cuda  (Прочитано 9629 раз)
Dilim
Гость
« : Ноябрь 06, 2014, 15:39 »

Здравствуйте! Столкнулся я с такой проблемой: создаю QGLWidget, определяю функцию initializeGL()
Код:
void GLWidget::initializeGL()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
    glDisable(GL_DEPTH_TEST);

    // viewport
    glViewport(0, 0, window_width, window_height);

    // projection
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

initglew();

createVBO(&vboPos, &cuda_vbo_resource_pos,2);
createVBO(&vboColor, &cuda_vbo_resource_color,2);
runCudaPos(&cuda_vbo_resource_pos);
runCudaColor(&cuda_vbo_resource_color);
}
функции createVBO и runCuda.... выдраны из примера по совместимости opengl и cuda, который идёт вместе с cuda toolkit. В них создается буфер vbo и связывается с ресурсом cuda.
Код:
void runCudaColor(struct cudaGraphicsResource **vbo_resource)
{
float4 *dptr;
    checkCudaErrors(cudaGraphicsMapResources(1, vbo_resource, 0));
    size_t num_bytes;
    checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void **)&dptr, &num_bytes,
                                                         *vbo_resource));
   
    launch_kernel_color(dptr, dmesh_width, dmesh_height, g_fAnim);

    // unmap buffer object
    checkCudaErrors(cudaGraphicsUnmapResources(1, vbo_resource, 0));
}


Функцию paintGL() определяю следующим образом:
Код:
void display(GLuint *vboPos, GLuint *vboColor)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

     // set view matrix
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
   

     // render from the vbo
glEnableClientState  ( GL_VERTEX_ARRAY );
    glBindBuffer(GL_ARRAY_BUFFER, *vboPos);
    glVertexPointer(4, GL_FLOAT, 0, 0);

glEnableClientState  ( GL_COLOR_ARRAY );
glBindBuffer(GL_ARRAY_BUFFER, *vboColor);
glColorPointer(4, GL_FLOAT, 0, 0);

//glColor3f(1.0, 0.0, 0.0);
     glDrawArrays(GL_POINTS, 0, dmesh_width * dmesh_height);
     glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

   
}
void GLWidget::paintGL()
{
display(&vboPos, &vboColor);
swapBuffers();

}

Проблема заключается в том, что функцию runCudaColor получается вызвать только один раз, если QGLWidget имеет параметр SampleBuffer и только два раза, если QGLWidget имеет DoubleBuffer. Падает функция на строчке checkCudaErrors(cudaGraphicsMapResources(1, vbo_resource, 0)); т.е. при попытке обращения к ресурсу. Такое ощущение, что при вызове paintGL ресурс cuda_vbo_resource_color занимается и больше никогда не освобождается. Подскажите пожалуйста как освободить ресурс после отрисовки?
Записан
Dilim
Гость
« Ответ #1 : Ноябрь 07, 2014, 15:00 »

дело похоже не в занятости ресурса, а в контесте OGL. Функция cudaGraphicsMapResources возвращает cudaErrorInvalidGraphicsContext после второго вызова. Получается сначала всё хорошо, но потом paintGL() каким то образом портит контекст? Или я что то не так понимаю?
Записан
vulko
Гость
« Ответ #2 : Ноябрь 07, 2014, 15:05 »

дело похоже не в занятости ресурса, а в контесте OGL. Функция cudaGraphicsMapResources возвращает cudaErrorInvalidGraphicsContext после второго вызова. Получается сначала всё хорошо, но потом paintGL() каким то образом портит контекст? Или я что то не так понимаю?

swapBuffers точно нужен?
попробуй добавить вызов makeCurrent(), если проблема в контексте.
Записан
vulko
Гость
« Ответ #3 : Ноябрь 07, 2014, 15:06 »

если можешь, закинь весь проект. так не совсем понятно.
Записан
Dilim
Гость
« Ответ #4 : Ноябрь 07, 2014, 15:35 »

swapBuffers точно нужен?
попробуй добавить вызов makeCurrent(), если проблема в контексте.

swapBuffers нужен, когда буфер двойной..
целиком проект слишком большой, в архиве только часть файлов
Записан
vulko
Гость
« Ответ #5 : Ноябрь 10, 2014, 08:50 »

swapBuffers точно нужен?
попробуй добавить вызов makeCurrent(), если проблема в контексте.

swapBuffers нужен, когда буфер двойной..
целиком проект слишком большой, в архиве только часть файлов


qglwidget автоматом свапает буферы после paintGL(). ручками нужно вызывать только если 2 потока работают с буфером.
тогда нужно makeCurrent() и doneCurrent() вызывать ещё.

поэтому и просил весь проект, если возможно. так не понятно...

ещё стоит добавить после glDrawArrays
glBindBuffer(GL_ARRAY_BUFFER, 0);

Ну и glBindBuffer(GL_ARRAY_BUFFER, *vboPos); насколько мне известно в качестве второго аргумента ждет индекс буфера, а не указатель на него.
Записан
Dilim
Гость
« Ответ #6 : Ноябрь 12, 2014, 14:43 »

qglwidget автоматом свапает буферы после paintGL(). ручками нужно вызывать только если 2 потока работают с буфером.
тогда нужно makeCurrent() и doneCurrent() вызывать ещё.

поэтому и просил весь проект, если возможно. так не понятно...

ещё стоит добавить после glDrawArrays
glBindBuffer(GL_ARRAY_BUFFER, 0);

Ну и glBindBuffer(GL_ARRAY_BUFFER, *vboPos); насколько мне известно в качестве второго аргумента ждет индекс буфера, а не указатель на него.

не, проблема не в этом. я создал ещё один проект, там всё прекрасно работает. разница в том, что не рабочий получает данные на отрисовку через winpcap, а рабочий генерит данные сам, причем интерфейс для получения данных один и тот же, я уже не знаю куда копать..
« Последнее редактирование: Ноябрь 17, 2014, 11:25 от Dilim » Записан
vulko
Гость
« Ответ #7 : Ноябрь 12, 2014, 15:00 »

qglwidget автоматом свапает буферы после paintGL(). ручками нужно вызывать только если 2 потока работают с буфером.
тогда нужно makeCurrent() и doneCurrent() вызывать ещё.

поэтому и просил весь проект, если возможно. так не понятно...

ещё стоит добавить после glDrawArrays
glBindBuffer(GL_ARRAY_BUFFER, 0);

Ну и glBindBuffer(GL_ARRAY_BUFFER, *vboPos); насколько мне известно в качестве второго аргумента ждет индекс буфера, а не указатель на него.

не, проблема не в этом. я создал ещё один проект, там всё прекрасно работает. разница в том, что не рабочий получает данные на отрисовку через winpcap, а рабочий генерит данные сам, причем интерфейс для получения данных один и тот же, я уже не знаю куда копать..

это не очень проект, я такое врядли смогу запустить...))

checkCudaErrors(cudaGraphicsMapResources(1, vbo_resource, 0));
падает с какой ошибкой?

checkCudaErrors отрабатывает? в смысле выдает что-то в консоль об ошибки, или при выполнении вылетает?

если есть работающее приложение, и точно такое же неработающее, значит проблема в том как работает отваливающееся приложение, другого не дано.
поподробнее опиши что конкретно падает, с какими ошибками и т.п.

стэк сюда скопипасти при крэше.
Записан
Dilim
Гость
« Ответ #8 : Ноябрь 12, 2014, 15:07 »

это не очень проект, я такое врядли смогу запустить...))

checkCudaErrors(cudaGraphicsMapResources(1, vbo_resource, 0));
падает с какой ошибкой?

checkCudaErrors отрабатывает? в смысле выдает что-то в консоль об ошибки, или при выполнении вылетает?

если есть работающее приложение, и точно такое же неработающее, значит проблема в том как работает отваливающееся приложение, другого не дано.
поподробнее опиши что конкретно падает, с какими ошибками и т.п.

стэк сюда скопипасти при крэше.
падает с такой ошибкой: CUDA error code=79(cudaErrorInvalidGraphicsContext)  причем только после третьего вызова, первые два отрабатывает нормально: CUDA error code=0(cudaSuccess) 
а как, прости за тупой вопрос, стэк скопировать?
Записан
vulko
Гость
« Ответ #9 : Ноябрь 12, 2014, 15:27 »

это не очень проект, я такое врядли смогу запустить...))

checkCudaErrors(cudaGraphicsMapResources(1, vbo_resource, 0));
падает с какой ошибкой?

checkCudaErrors отрабатывает? в смысле выдает что-то в консоль об ошибки, или при выполнении вылетает?

если есть работающее приложение, и точно такое же неработающее, значит проблема в том как работает отваливающееся приложение, другого не дано.
поподробнее опиши что конкретно падает, с какими ошибками и т.п.

стэк сюда скопипасти при крэше.
падает с такой ошибкой: CUDA error code=79(cudaErrorInvalidGraphicsContext)  причем только после третьего вызова, первые два отрабатывает нормально: CUDA error code=0(cudaSuccess) 
а как, прости за тупой вопрос, стэк скопировать?

в creator'е можно правой кнопкой тыркнуть на стеке и нажать копировать.
print screen работает всегда.

стек отображает ессесно тока в дебаге (ну и вруби window->views->stack, если его не видно).
ну и это только если приложение крэшится, а не просто печатается куда ошибка в консоль.

я верно понимаю, что ты из pcap файла сам парсишь данные? возможно они кривые? возможно данные вообще кривые, которые ты в vbo подгружаешь, отсюда и ошибка...

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

посмотри на дебаге что лежит внутри vbo_resource когда ошибка выскакивает.
Записан
Dilim
Гость
« Ответ #10 : Ноябрь 13, 2014, 14:40 »

о как! оказалось всё дело в потоках! я создаю объект QThread и из него передаю данные в основной поток на отрисовку. так вот в неработающем случае я передаю данные из функции run и эти данные почему не нравятся функции cudaGraphicsMapResources в основном потоке. надо дальше копать..
Записан
vulko
Гость
« Ответ #11 : Ноябрь 13, 2014, 15:04 »

о как! оказалось всё дело в потоках! я создаю объект QThread и из него передаю данные в основной поток на отрисовку. так вот в неработающем случае я передаю данные из функции run и эти данные почему не нравятся функции cudaGraphicsMapResources в основном потоке. надо дальше копать..

а как передаешь данные?
Записан
Dilim
Гость
« Ответ #12 : Ноябрь 14, 2014, 11:19 »

а как передаешь данные?

когда формирование выборки заканчивается посылаю сигнал с указателем на начало выборки, а в слоте беру данные по этому указателю и копирую в память видяхи.
Записан
vulko
Гость
« Ответ #13 : Ноябрь 14, 2014, 11:23 »

а как передаешь данные?

когда формирование выборки заканчивается посылаю сигнал с указателем на начало выборки, а в слоте беру данные по этому указателю и копирую в память видяхи.

с каких пор в сигнале можно указатель передавать?

ты бы проверил что там вообще приходит...

сигнал queued?

может лучше скопировать в память видяхи в том же потоке где формируется выборка, а передавать просто ID буфера?
тут главное не забыть сделать gl context основным из потока.
если не ошибаюсь, vbo жестко привязаны к контексту.
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #14 : Ноябрь 14, 2014, 11:45 »

а как передаешь данные?

когда формирование выборки заканчивается посылаю сигнал с указателем на начало выборки, а в слоте беру данные по этому указателю и копирую в память видяхи.

с каких пор в сигнале можно указатель передавать?


С давних Улыбающийся
Пример из доки: http://qt-project.org/doc/qt-4.8/qactiongroup.html#hovered
Записан

Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.06 секунд. Запросов: 23.