Hello,
I would like to copy the render frame to en openCV GpuMat.
GpuMat use cuda so I’ve decided first to copy the render frame to cuda.
- I retrieve the render frame using OnBackBufferReadyToPresent delegate
- In the delegate I get the native resource of the texture:
struct DX12Texture
{
void* handle;
ID3D12Resource* resource;
unsigned long long memSize;
};
void MyActor::OnGetRendering(SWindow& Window, const FTexture2DRHIRef& Texture) const
{
static HANDLE SharedHandle = nullptr;
if (GDynamicRHI)
{
ID3D12Resource* NativeResource
= reinterpret_cast<ID3D12Resource*>(Texture->GetNativeResource());
if (NativeResource)
{
ID3D12Device* Device
= reinterpret_cast<ID3D12Device*>(GDynamicRHI->RHIGetNativeDevice());
//Device->GetAdapterLuid();
if (SharedHandle == nullptr)
{
WindowsSecurityAttributes windowsSecurityAttributes;
LPCWSTR name = nullptr;
HRESULT Result = Device->CreateSharedHandle(
NativeResource,
&windowsSecurityAttributes,
GENERIC_ALL,
name,
&SharedHandle);
}
D3D12_RESOURCE_DESC Desc = NativeResource->GetDesc();
D3D12_RESOURCE_ALLOCATION_INFO allocInfo = Device->GetResourceAllocationInfo(0, 1, &Desc);
DX12Texture Texture{ SharedHandle, NativeResource, allocInfo.SizeInBytes };
// copy to cuda
CaptureDX12(Texture);
DebugUI->bTakeScreenshot = false;
}
}
CaptureDX12( DX12Texture& d3d12Texture)
{
cv::cuda::GpuMat mat;
getExternalMemory(d3d12Texture);
mapMemory(mat, d3d12Texture);
}
void OptroD3D12Interop::mapMemory(cv::cuda::GpuMat& mat, DX12Texture& d3d12Texture)
{
void* pData = nullptr;
cudaExternalMemoryBufferDesc buffDesc{};
memset(&buffDesc, 0, sizeof(buffDesc));
buffDesc.offset = 0;
buffDesc.size = d3d12Texture.memSize;
cudaExternalMemoryGetMappedBuffer(&pData, m_externalMemory, &buffDesc);
mat = cv::cuda::GpuMat(static_cast<int>(d3d12Texture.resource->GetDesc().Height),
static_cast<int>(d3d12Texture.resource->GetDesc().Width),
cv::directx::getTypeFromDXGI_FORMAT(d3d12Texture.resource->GetDesc().Format), pData);
}
void getExternalMemory(DX12Texture& d3d12Texture)
{
cudaExternalMemoryHandleDesc memDesc{};
memset(&memDesc, 0, sizeof(memDesc));
memDesc.type = cudaExternalMemoryHandleTypeD3D12Resource;
memDesc.handle.win32.handle = d3d12Texture.handle;
memDesc.size = d3d12Texture.memSize;
memDesc.flags = cudaExternalMemoryDedicated;
cudaImportExternalMemory(&m_externalMemory, &memDesc);
}
My problem is cudaImportExternalMemory
wich block the application.
I know it’s a cuda mistake but am I in the good way for my purpose ?
Thanks,
Sorry for my terrible english.