cuda cuvid problems note D3Dtexture opengl texture mapped

8 篇文章 0 订阅
6 篇文章 0 订阅

1、cuda驱动api与cuda runtime 混合使用造成问题。
目的:将画面cuvid解析出来的yuv 渲染 到 texture(opengl的或D3d的)上
因为官网给出的demo 是利用cuda驱动api来进行开发的。而官网给出的从texture映射到cuda中的案例只有cuda runtime api的(在10.1版本中已经被deprecated 了)。并且也没有从cuda驱动中找到从texture映射到cuda的接口。所以一开始代码是cuvid这边仿照cuda给出的原生代码使用cuda驱动来初始化一些临时和中间变量  ,而渲染的目标对象用cuda runtime api 来初始化。

然后碰到了如何将数据从cuda驱动对象拷贝到cudaruntime对象的问题上,找了很久,没找到。放弃。(主要是对象类型没有找到该怎么转换,各种尝试都失败。cuMemcpy2DAsync)
然后修改cuvid这边代码,全部换成cudaruntime api和类型来实现。
下面这段代码是最终的解决方案。

cudaError_t err;
cudaArray *cuda_array;
err = cudaGraphicsSubResourceGetMappedArray(&cuda_array, frame->cuda_resource1, 0, 0);
err = cudaMemcpy2DToArrayAsync(cuda_array, 0, 0, (void*)dpSrcFrame, nSrcPitch,m_nWidth, m_nLumaHeight, cudaMemcpyHostToDevice);

//cudaMemcpy();
err = cudaGraphicsSubResourceGetMappedArray(&cuda_array, frame->cuda_resource2, 0, 0);
err = cudaMemcpy2DToArrayAsync(cuda_array, 0, 0, (uint8_t*)dpSrcFrame+ nSrcPitch*m_nSurfaceHeight, nSrcPitch, m_nWidth, m_nChromaHeight, cudaMemcpyHostToDevice);  //chromaheight is half of lumaheight in nv12 case 
if (m_nNumChromaPlanes == 2)
{
	//CudaResourceMap(frame->cuda_resource3);
	//m.srcDevice = (CUdeviceptr)((uint8_t *)dpSrcFrame + m.srcPitch * m_nSurfaceHeight * 2);
	//m.dstDevice = (CUdeviceptr)(m.dstHost = frame->cuda_resource3);
	//m.Height = m_nChromaHeight;
	//ret = cuMemcpy2DAsync(&m, m_cuvidStream);
	//cudaTestError("cuda memcpy 3 failed\n");
	err = cudaGraphicsSubResourceGetMappedArray(&cuda_array, frame->cuda_resource3, 0, 0);
	err = cudaMemcpy2DToArrayAsync(cuda_array, 0, 0, (uint8_t*)dpSrcFrame + nSrcPitch*m_nSurfaceHeight*2, nSrcPitch, m_nWidth, m_nChromaHeight, cudaMemcpyHostToDevice);
}

对于从texture 拷贝到cudaGraphicsResource,必须使用memcpy2darray 的方式。普通的memcpy会失败。
frame->cuda_resource1 ... 是cudaGraphicsResource对象, 用于记录从texture映射到cuda的地址。其映射过程如下。相当于cuda指针指向texture,他们实际上时共用了一块存储空间。

cudaError_t err = cudaError_t::cudaSuccess;
#ifdef _WIN32
if (Render::get()->getAPI() == Render::API_DIRECT3D11)
{
	m_isD3d = true;
	ID3D11Texture2D *d3d11_texture = static_cast<ID3D11Texture2D*>(texture1->getD3D11Texture());
	err  = cudaGraphicsD3D11RegisterResource(&cuda_resource1, d3d11_texture, cudaGraphicsRegisterFlagsNone);

	d3d11_texture = static_cast<ID3D11Texture2D*>(texture2->getD3D11Texture());
	err = cudaGraphicsD3D11RegisterResource(&cuda_resource2, d3d11_texture, cudaGraphicsRegisterFlagsNone);
		
	d3d11_texture = static_cast<ID3D11Texture2D*>(texture3->getD3D11Texture());
	err = cudaGraphicsD3D11RegisterResource(&cuda_resource3, d3d11_texture, cudaGraphicsRegisterFlagsNone);
}
#endif
if (Render::get()->getAPI() == Render::API_OPENGL)
{
	m_isOpengl = false;
	GLuint gl_texture = static_cast<GLuint>(texture1->getGLTextureID());
	GLuint gl_target = static_cast<GLuint>(texture1->getGLTarget());
	err = cudaGraphicsGLRegisterImage(&cuda_resource1, gl_texture, gl_target, cudaGraphicsRegisterFlagsNone);

	gl_texture = static_cast<GLuint>(texture2->getGLTextureID());
	gl_target = static_cast<GLuint>(texture2->getGLTarget());
	err = cudaGraphicsGLRegisterImage(&cuda_resource2, gl_texture, gl_target, cudaGraphicsRegisterFlagsNone);
		
	gl_texture = static_cast<GLuint>(texture3->getGLTextureID());
	gl_target = static_cast<GLuint>(texture3->getGLTarget());
	err = cudaGraphicsGLRegisterImage(&cuda_resource3, gl_texture, gl_target, cudaGraphicsRegisterFlagsNone);
}

if (!cuda_resource1|| !cuda_resource2|| !cuda_resource3)//|| !cuda_resourceu || !cuda_resourcey
	Log::fatal("Unsupported render api\n");
	
err = cudaGraphicsMapResources(1, &cuda_resource1, 0);
err = cudaGraphicsMapResources(1, &cuda_resource2, 0);
err = cudaGraphicsMapResources(1, &cuda_resource3, 0);

cudaMemcpy2DToArrayAsync 在10.1 版本中好像被deprecated。直接添加一句代码#pragma warning(disable:4996)。

最终达到预期

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值