Hi,
I have read multiple examples of how to do this such as this, this and this. There are, however, still issues that I cannot solve. Any help would be appreciated.
I have created this function to get the handle for the Vulkan Image memory:
int GpuVulkan::getResultHandle()
{
vk::MemoryGetFdInfoKHR memoryGetInfo;
memoryGetInfo .setPNext(nullptr)
.setMemory(textures.images[0].image.textureImageMemory.get())
.setHandleType(vk::ExternalMemoryHandleTypeFlagBitsKHR::eOpaqueFd);
int handle{-1};
auto getMemoryInfoFdKHR = (PFN_vkGetMemoryFdKHR)device->getProcAddr("vkGetMemoryFdKHR");
auto mgi = static_cast<VkMemoryGetFdInfoKHR>(memoryGetInfo);
getMemoryInfoFdKHR(device.get(), &mgi ,&handle);
return handle;
}
Then I have a class for the CUDA computations where I wanted to map this image and write something in it:
ComputeCuda::ComputeCuda(int rh, int width, int height) : Compute(rh)
{
CUDA_EXTERNAL_MEMORY_HANDLE_DESC handleDesc;
handleDesc.type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD;
handleDesc.handle.fd = rh;
handleDesc.size = width*height*4;
cuImportExternalMemory(&externalImageMemory, &handleDesc);
CUmipmappedArray mipmapArray;
CUDA_ARRAY3D_DESCRIPTOR arrayDesc = { };
arrayDesc.Width = width;
arrayDesc.Height = height;
arrayDesc.Depth = 0;
arrayDesc.Format = CU_AD_FORMAT_UNSIGNED_INT8;
arrayDesc.NumChannels = 4;
arrayDesc.Flags = CUDA_ARRAY3D_COLOR_ATTACHMENT;
CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC mipmapArrayDesc;
mipmapArrayDesc.arrayDesc = arrayDesc;
mipmapArrayDesc.numLevels = 1;
mipmapArrayDesc.offset = 0;
cuExternalMemoryGetMappedMipmappedArray(&mipmapArray, externalImageMemory, &mipmapArrayDesc);
std::cerr << "error:" << cuMipmappedArrayGetLevel(reinterpret_cast<CUarray*>(&resultArray), mipmapArray, 0);
}
__global__ void test(cudaSurfaceObject_t result)
{
unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;
uchar4 c = {255,255,255,255};
surf2Dwrite(c ,result, x*sizeof(uchar3), y);
}
void ComputeCuda::compute()
{
cudaResourceDesc rd;
memset(&rd, 0, sizeof(rd));
rd.resType = cudaResourceTypeArray;
rd.res.array.array = resultArray;
std::cerr <<"aaa";
cudaCreateSurfaceObject(&resultSurface, &rd);
test<<<10,256>>>(resultSurface);
}
I have struggled with some deprecated examples of the external memory management and also the type casting such as the reinterpret_cast
that I had to use and didn’t see it in another examples but I think that this should be working well. However, I got a Segmentation Fault at the cudaCreateSurfaceObject
function and 709 cudaErrorContextIsDestroyed
error at cuMipmappedArrayGetLevel
. I am now kinda clueless about where the problem might be.
Thanks and have a nice day
EDIT:
Had to use cudaSetDevice and cuCtxCreate to fix the context error but still getting Bus error instead.