我在C侧有一个1通道浮动图像,如下所示:
int width, height;
float* img;
Run Code Online (Sandbox Code Playgroud)
我想将此图像传递给CUDA纹理.我正在阅读NVIDIA CUDA C编程指南(第42-43页)并使用本教程编写了如下代码:
main.cpp中:
int main()
{
int width, height;
float* h_Input;
ReadImage(&h_Input, &width, &height); // My function which reads the image.
WriteImage(h_Input, width, height); // works perfectly...
float* h_Output = (float*) malloc(sizeof(float) * width * height);
CalculateWithCuda(h_Input, h_Output, width,height);
WriteImage(h_Output, width, height); // writes an empty-gray colored image.... *WHY???*
}
Run Code Online (Sandbox Code Playgroud)
kernel.cu:
texture<float, cudaTextureType2D, cudaReadModeElementType> texRef; // 2D float texture
__global__ void Kernel(float* output, int width, int height)
{
int i = blockIdx.y * blockDim.y + threadIdx.y; // row number
int j = blockIdx.x * blockDim.x + threadIdx.x; // col number
if(i < height && j < width)
{
float temp = tex2D(texRef, i + 0.5f, j + 0.5f);
output[i * width + j] = temp ;
}
}
void CalculateWithCuda(const float* h_input, float* h_output, int width, int height)
{
float* d_output;
// Allocate CUDA array in device memory
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(32, 0, 0, 0,cudaChannelFormatKindFloat);
cudaArray* cuArray;
cudaMallocArray(&cuArray, &channelDesc, width, height);
// Copy to device memory some data located at address h_data in host memory
cudaMemcpyToArray(cuArray, 0, 0, h_input, width * height * sizeof(float) , cudaMemcpyHostToDevice);
// Set texture parameters
texRef.addressMode[0] = cudaAddressModeWrap;
texRef.addressMode[1] = cudaAddressModeWrap;
texRef.filterMode = cudaFilterModeLinear;
texRef.normalized = true;
// Bind the array to the texture reference
cudaBindTextureToArray(texRef, cuArray, channelDesc);
// Allocate GPU buffers for the output image ..
cudaMalloc(&d_output, sizeof(float) * width * height);
dim3 threadsPerBlock(16,16);
dim3 numBlocks((width/threadsPerBlock.x) + 1, (height/threadsPerBlock.y) + 1);
Kernel<<<numBlocks, threadsPerBlock>>>(d_output, width,height);
cudaDeviceSynchronize();
// Copy output vector from GPU buffer to host memory.
cudaMemcpy(h_output, d_output, sizeof(float) * width * height, cudaMemcpyDeviceToHost);
// Free GPU memory ...
}
Run Code Online (Sandbox Code Playgroud)
正如我在代码中所说; 这个内核必须从纹理中读取并给出与输出相同的图像.但是,我正在为输出拍摄一个空的(灰色)图像.我刚刚在教程中实现了相同的方法,为什么这个纹理不起作用?
如果有人告诉我解决这个问题的方法,我将不胜感激......
PS:当然,这不是所有的代码.我刚刚复制了必要的部分.如果您需要其他细节,我也会支持.
提前致谢.
使用标准化坐标时,通过0到1(不包括)的坐标访问纹理.您忘记将基于threadIdx的整数坐标转换为规范化.
unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;
float u = x / (float)width;
float v = y / (float)height;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4641 次 |
| 最近记录: |