1

ここでは、2つの異なるバージョンのコードがあります。

1つ目は、CUDASDKからの完全なCUDAプログラムです。カーネルでは、tex3Dがうまく機能します。

2番目のバージョンは、多くのOpenGL関数とOpenGLテクスチャを備えたより複雑です。その.cuファイルは最初のものと同じです。ただし、cudaMalloc変数を使用して、同じカーネル関数でtex3Dから値を取得しましたが、tex3D関数は何も返さないことがわかりました。実際、2つのプログラムは、以下のコードと同じ方法で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(&copyParams) ); 

以下のコードは、tex3Dを呼び出すカーネル関数です。実際には、レイキャスティングの実装であるCUDASDKvolumeRenderのカーネルとまったく同じです。

__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
}

これらのコードのほとんどはCUDASDKvolumeRenderからのものであり、私の最初のバージョンのコードでうまく機能するため、これらのコードは優れていると思います。

しかし、2番目のバージョンでtex3Dが突然無効になる理由がわかりません。たぶん、他のいくつかのOpenGLテクスチャがいくつかの悪影響を及ぼしますか?

4

1 に答える 1

3

実際、問題は、CUDAデバイスを選択する前にbind-texture-stuffを実行することです。したがって、最初にcudaChooseDeviceとcudaSetGLDeviceを呼び出すと、うまく機能します。

于 2012-06-07T01:55:56.460 に答える