CUDA与OpenGL交互问题,求救

大牛们,你们好。 我 最近在做用CUDA编程做一个YUV视频优化的程序。
现在已经进展到这一步了,
YUV的视频文件读取到CPU内存当中,并拷贝给GPU上的内存,在 GPU上进行YUV到RGB的转换后,再将转换后的数据拷贝出来,在CPU端窗口上显示。这些都实现了,能正确地播放视频画面。
现在我想做的是, 在GPU上YUV转RGB后,不进行拷贝,直接把RGB数据绑定给一个二维纹理,然后在CPU端利用OpenGL的缓存对象进行映射,然后进行渲染播放。

以下是我写的接口

.cu文件

texture<uint, 2, CudaReadModeElementType> tex;
// 这里纹理参考是该用float, 还是该用UINT? 因为我的纹理数据在GPU全局内存中,每个像素是3个BYTE
__global__static void d_render(float*d_output, int imageW, int imageH)
{
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;

float u = x / (float)imageW;
float v = y / (float)imageH;

if(x<imageW && y<imageH)
{
int i = y * imageW + x;
d_output = tex2D(tex, u, v);
}
__syncthreads();
}

void InitTexture(BYTE*RGBbuf, int width, int height)
{
cudaChannelFormatDesc channelDesc = cudaCreateChannel();
size_t size = width * height * sizeof(uint) ;

//上面这句该不该这么写。 还是写成其他的?因为实际上只有width *height * sizeof(BYTE) * 3这么大的一块内存

tex.normalized = true;
tex.filterMode = cudaFilterModeLinear;
tex.addressMode[0] = cudaAddressModeClamp;
tex.addressMode[1] = cudaAddressModeClamp;
cudaBindTexture2D(0, &tex, (void*)RGBbuf, &channelDesc, width, height, size);
}

extern “C” void run_kernel(float*d_output, int width, int height)
{
.
.
.

// 到这里,gpu上已经完成YUV到RGB的转换,并且像素数据保存在gpu_RGB指向的全局内存快。
dim3 block(32, 16, 1);
dim3 grid(11, 18, 1);
// 块的划分是依据画面大小是352288 = 32161118, 让每个块运行512条线程,每个线程处理一个像素。

InitTexture(gpu_RGB, width, height);
d_render<<<grid, block, 0>>>(d_output, width, height, 0);
cudaError_t err = cudaGetLastError(); // 这里调试的时候,提示没有错误。
.
.
.
}

.cpp 中视窗的接口
// 像素缓存的初始化
void ChildWindow::InitPixBuffer()
{
.
.
.

// 在这之前,我确保OpenGL的窗口设置已经完成, 因为我直接调用openGL的一些函数能在窗口画出图来。
glewInit();
cudaGLsetDevice(cutGetMaxGflopsDeviceId());
glGenBuffersARB(1, &m_pbo); // m_pbo是GLuint类型
glBindbufferARB(GL_ARRAY_BUFFER, m_pbo);

glBufferDataARB(GL_ARRAY_BUFFER, iWidth * iHeight * sizeof(uint), 0, GL_DYNAMIC_DRAW);

cudaGLRegisterBufferObject(m_pbo);
}

void ChildWindow::render()
{
cudaGLMapBufferObject((void**)&m_ndevptr, m_pbo); // m_ndevptr是uint*型

run_Cuda(Y, Cb, Cr, RGBbuf, m_ndevptr, width, height);
// 上面这个接口是内核程序DLL导出的接口,内部调用了run_kernel

cudaGLUnmapBufferObject(m_pbo);
glDisable(GL_DEPTH_TEST);
glRasterPos2i(0, 0);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_pbo);
glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, 0);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);

}
代码里的width 是指图像的宽度 352, height是图像的高度288.

在 窗口那端,先调用InitPixBuffer(),再在OnPaint()里调用render();
现在视频画面显示不出来,窗口显示带花线的黑屏。
向大侠求救

没人回帖
我顶

哎!没写过OpenGL和CUDA互操作的程序,不能给你解决问题,同顶!

我再顶

不懂 ,帮你顶下:rolleyes:

email里面已经回复了。。。

我也遇到了楼上类似的问题,麻烦勇哥也给我解答一下,谢谢了,我的邮箱地址:wangpichao@126.com

楼主你好,我现在也在做yuv到rgb的转换问题,遇到了和你一样的问题,楼主能分享你的解决方案么?谢谢了,我的邮箱:wangpichao@126.com

我也遇到了楼主类似的问题,也麻烦勇哥给俺解答一下,非常谢谢了。
我的邮箱地址:ymmtommy@163.com

我也有楼主类似的问题,麻烦勇哥给解答一下,非常谢谢!!
我的邮箱地址:xdh0512@163.com

貌似必须进行拷贝,不能直接把RGB数据绑定给一个二维纹理

貌似这个问题很普遍啊,同求解答