Directx 立即将NV12复制到ID3D11Texture2D

Directx 立即将NV12复制到ID3D11Texture2D,directx,rendering,directx-11,memcpy,nv12-nv21,Directx,Rendering,Directx 11,Memcpy,Nv12 Nv21,我有一个解码器,可以产生NV12 yuv帧。我想做的是用单个memcpy将该帧复制到ID3D11Texture2D纹理。因为D3D11_MAPPED_子资源的行间距与我的NV12帧不同,所以我必须逐行复制整个yuv,这非常昂贵。有更好的方法吗 我试图找到关于这个话题的任何信息,但到目前为止没有任何运气 // Copy from CPU access texture to bitmap buffer D3D11_MAPPED_SUBRESOURCE resource; UINT subresour

我有一个解码器,可以产生NV12 yuv帧。我想做的是用单个memcpy将该帧复制到ID3D11Texture2D纹理。因为D3D11_MAPPED_子资源的行间距与我的NV12帧不同,所以我必须逐行复制整个yuv,这非常昂贵。有更好的方法吗

我试图找到关于这个话题的任何信息,但到目前为止没有任何运气

// Copy from CPU access texture to bitmap buffer
D3D11_MAPPED_SUBRESOURCE resource;
UINT subresource = D3D11CalcSubresource(0, 0, 0);
OutMgr.m_DeviceContext->Map(OutMgr.m_texture, subresource, D3D11_MAP_WRITE_DISCARD, 0, &resource);

BYTE* dptr = reinterpret_cast<BYTE*>(resource.pData);

for (int i = 0; i < nv12Frame->height; i++)
{
    memcpy(dptr + resource.RowPitch * i, nv12Frame->Y + nv12Frame->pitch * i, nv12Frame->pitch);
}

for (int i = 0; i < nv12Frame->height / 2; i++)
{
    memcpy(dptr + resource.RowPitch *(nv12Frame->height + i), nv12Frame->UV + nv12Frame->pitch * i, nv12Frame->pitch);
}

OutMgr.m_DeviceContext->Unmap(OutMgr.m_texture, subresource);
//从CPU访问纹理复制到位图缓冲区
D3D11_映射_子资源;
UINT subresource=d3d11calsubresource(0,0,0);
OutMgr.m_设备上下文->映射(OutMgr.m_纹理、子资源、D3D11_映射、写入、丢弃、0和资源);
字节*dptr=reinterpret_cast(resource.pData);
对于(int i=0;iheight;i++)
{
memcpy(dptr+resource.RowPitch*i,nv12Frame->Y+nv12Frame->pitch*i,nv12Frame->pitch);
}
对于(int i=0;iheight/2;i++)
{
memcpy(dptr+resource.RowPitch*(nv12Frame->height+i),nv12Frame->UV+nv12Frame->pitch*i,nv12Frame->pitch);
}
OutMgr.m_设备上下文->取消映射(OutMgr.m_纹理,子资源);

IMHO与您的NV12框架的布局这是正确复制它的最快方法。memcpy应该是SSE2优化的(如果SSE2可用的话),所以在现代CPU和编译器上应该非常快。另一种方法可能涉及计算甚至像素着色器(使用渲染目标纹理),但无论如何都需要将nv12Frame上载到着色器。对于nv12Frame的布局,这是正确复制它的最快方法。memcpy应该是SSE2优化的(如果SSE2可用的话),所以在现代CPU和编译器上应该非常快。另一种方法可能涉及某种方式的计算甚至像素着色器(使用渲染目标纹理),但无论如何都需要将nv12Frame上载到着色器。