I have an application that renders graphics using CUDA and displays them on Windows 7 via DX11. In CUDA 3.0, I accomplish this by rendering to a linear pixel array, then using cudaMemcpyToArray to copy the pixels to a DX11 render buffer (texture) that has been mapped to a CUDA Array. This works fine, but (1) is slow, and (2) requires interaction with the CPU to issue the copy command.
CUDA 3.1 adds the ability to bind a CUDA array to a Surface reference, which can be written directly, avoiding the memcpy. Unfortunately, only arrays allocated by cudaMallocArray with a special “cudaArraySurfaceLoadStore” flag appear to be eligible for Surface binding. In particular, attempting to bind an array obtained via cudaGraphicsSubResourceGetMappedArray returns cudaErrorInvalidValue. Is there any way to make the mapped array acceptable to the Surface binding code? Thanks!
In the code below, only the final assert fails…
[codebox]
// set up CUDA view of DX backbuffer on device
ID3D11Texture2D *backBuffer; // omitting initialization for brevity
D3D11_TEXTURE2D_DESC d;
backBuffer->GetDesc(&d);
int err;
cudaGraphicsResource *backBufferResource = NULL;
err = cudaGraphicsD3D11RegisterResource(&backBufferResource, backBuffer, cudaGraphicsRegisterFlagsNone);
assert(err == CUDA_SUCCESS);
cudaArray *backBufferCudaArray = NULL;
err = cudaGraphicsResourceSetMapFlags(backBufferResource, cudaGraphicsMapFlagsNone);
assert(err == CUDA_SUCCESS);
err = cudaGraphicsMapResources(1, &backBufferResource, (cudaStream_t)0);
assert(err == CUDA_SUCCESS);
err = cudaGraphicsSubResourceGetMappedArray(&backBufferCudaArray, backBufferResource, 0, 0);
assert(err == CUDA_SUCCESS);
struct cudaChannelFormatDesc chDesc = cudaCreateChannelDesc(8, 8, 8, 8, cudaChannelFormatKindUnsigned);
struct surfaceReference *drawingSurfaceReference;
err = cudaGetSurfaceReference((const struct surfaceReference **)&drawingSurfaceReference, “drawingSurface”);
assert(err == CUDA_SUCCESS);
// the following returns err=11
err= cudaBindSurfaceToArray(drawingSurfaceReference, backBufferCudaArray, &chDesc);
assert(err == CUDA_SUCCESS); [/codebox]