В функции ядра CUDA, почему tex3D не может вернуть никакого значения?
Здесь у меня есть две разные версии моего кода.
Первая - это полная программа CUDA от CUDA SDK. В ядре tex3D работает хорошо.
Вторая версия более сложна со многими функциями OpenGL и текстурами OpenGL. Его.cu файл такой же, как и первый. Однако я использую переменную cudaMalloc для получения значения из tex3D в той же функции ядра, я обнаружил, что функция tex3D ничего не возвращает. На самом деле, две программы используют один и тот же способ для создания 3D текстур, как показано ниже:
#define SIZE_X 128 //numbers in elements
#define SIZE_Y 128
#define SIZE_Z 128
typedef float VolumeType;
cudaExtent volumeSize = make_cudaExtent(SIZE_X, SIZE_Y, SIZE_Z);
cudaArray *d_volumeArray = 0; //for tex
cudaArray *d_transferFuncArray; //for transferTex
texture<VolumeType, 3, cudaReadModeElementType> tex; // 3D texture
texture<float4, 1, cudaReadModeElementType> transferTex; // 1D transfer function texture
//initialize the 3d texture "tex" with a 3D array "d_volumeArray"
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<VolumeType>();
cutilSafeCall( cudaMalloc3DArray(&d_volumeArray, &channelDesc, volumeSize) );
// set texture parameters
tex.normalized = true; // access with normalized texture coordinates
tex.filterMode = cudaFilterModeLinear; // linear interpolation
tex.addressMode[0] = cudaAddressModeClamp; // clamp texture coordinates
tex.addressMode[1] = cudaAddressModeClamp;
CUDA_SAFE_CALL(cudaBindTextureToArray(tex, d_volumeArray, channelDesc));// bind array to 3D texture
//get the real value for 3D texture "tex"
float *d_volumeMem;
cutilSafeCall(cudaMalloc((void**)&d_volumeMem, SIZE_X*SIZE_Y*SIZE_Z*sizeof(float)));
.....//assign value to d_volumeMem in GPU. I've already checked the d_volumeMem is valid
//copy d_volumeMem to 3DArray
cudaMemcpy3DParms copyParams = {0};
copyParams.srcPtr = make_cudaPitchedPtr((void*)d_volumeMem, SIZE_X*sizeof(VolumeType), SIZE_X, SIZE_Y);
copyParams.dstArray = d_volumeArray;
copyParams.extent = volumeSize;
copyParams.kin = cudaMemcpyDeviceToDevice;
cutilSafeCall( cudaMemcpy3D(©Params) );
Код ниже - это функция ядра, вызывающая tex3D. Фактически, это то же самое, что и ядро CUDA SDK volumeRender, то есть реализация лучевого приведения.
__global__ void d_render(....)
{
......//ray-casting progress
float temp = tex3D(tex, pos1, pos2, pos3);
//pos1 pos2 pos3 is valid
//Here actually I use a cudaMalloc variable "s" to store the temp
//In the first version, s has different value for different position
//In the second version, temp is 0 all the time
......//ray-casting progress
}
Я думаю, что этот код хорош, потому что большинство из них от CUDA SDK volumeRender и хорошо работают в моей первой версии кода.
Но я понятия не имею, почему во второй версии tex3D вдруг становится недействительным. Может быть, некоторые другие текстуры OpenGL имеют некоторые негативные последствия?
1 ответ
На самом деле проблема в том, что я делаю bind-texture-stuff перед тем, как выбрать устройство CUDA. Таким образом, вызов cudaChooseDevice и cudaSetGLDevice в первую очередь заставит все работать хорошо!