I am writing a module which gets cv::cuda::GpuMat
data on gpu and draw it on QOpenGLWidget
. To accelarate the speed, I want to avoid downloading data from device to host.
This is the main code
void MyPainter::drawImage(QMatrix4x4 transform_matrix, const cv::Mat &img)
{
if(parent->context() == 0){
parent->makeCurrent();
}
shader_program->bind();
cv::cuda::GpuMat gpumat_img;
qDebug() << "upload img....";
gpumat_img.upload(img); // for test, because other modules are unfished
qDebug() << gpumat_img.empty() << gpumat_img.type() << "Finish upload";
qDebug() << gpumat_img.size().width << gpumat_img.size().height;
cv::ogl::Texture2D test_texture;
qDebug() << "copy to texture memory....";
test_texture.copyFrom(gpumat_img); // here raise an error.
qDebug() << "Finish copy";
test_texture.bind();
vbo.bind();
qDebug() << test_texture.size().width << test_texture.size().height;
shader_program->setUniformValue("matrix", transform_matrix);
shader_program->enableAttributeArray(MYSHADER_VERTEX_ATTRIBUTE);
shader_program->enableAttributeArray(MYSHADER_TEXCOORD_ATTRIBUTE);
shader_program->setAttributeBuffer(MYSHADER_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 2);
shader_program->setAttributeBuffer(MYSHADER_TEXCOORD_ATTRIBUTE, GL_FLOAT, 0, 2);
QOpenGLFunctions *gl_function_ptr = QOpenGLContext::currentContext()->functions();
gl_function_ptr->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
shader_program->release();
test_texture.release();
vbo.release();
}
The error tells “OpenCV(4.6.0) Error: Gpu API call (OS call failed or operation not supported on this OS) in `anonymous-namespace’::CudaResource::registerBuffer, file D:\lib\opencv_my\source\opencv-4.6.0\modules\core\src\opengl.cpp, line 176”
But if I use the cv::ogl::texture2D::copyFrom(cv::Mat)
instead of cv::ogl::texture2D::copyFrom(cv::cuda::GpuMat)
, it can work well.
I read some source code of opencv and find the error is appear at here:
void CudaResource::registerBuffer(GLuint buffer)
{
CV_DbgAssert( buffer != 0 );
if (buffer_ == buffer)
return;
cudaGraphicsResource_t resource;
cudaSafeCall( cudaGraphicsGLRegisterBuffer(&resource, buffer, cudaGraphicsMapFlagsNone) ); // here raise the error
release();
resource_ = resource;
buffer_ = buffer;
}
But i can’t find cudaGraphicsGLRegisterBuffer()
.
My environment
Qt 7.0.0
OpenCV 4.6.0
CUDA 11.6
Apologize for my poor English.