我正在运行CUDA 5.0,并使用670设置了compute_30,sm_30。
我通过以下方式创建了一个mipmapped数组:
cudaExtent size;
size.width = window_width; // 600
size.height = window_height; // 600
size.depth = 1;
int levels = getMipMapLevels(size);
levels = MIN(levels, 9); // 9
cudaChannelFormatDesc fp32;
fp32.f = cudaChannelFormatKindFloat;
fp32.x = fp32.y = fp32.z = fp32.w = 32;
cudaMipmappedArray_t A;
checkCuda(cudaMallocMipmappedArray(&A, &fp32, size, levels, cudaArraySurfaceLoadStore));
Run Code Online (Sandbox Code Playgroud)
我用surf2Dwrites加载A的第一级。我知道这可行,因为我将阵列复制到主机并将其转储到映像文件。现在,我希望用Mipmap填充A的其他Miplevel。通过该循环的一次迭代如下所示:
width >>= 1; width = MAX(1, width);
height >>= 1; height = MAX(1, height);
cudaArray_t from, to;
checkCuda(cudaGetMipmappedArrayLevel(&from, A, newlevel-1));
checkCuda(cudaGetMipmappedArrayLevel(&to, A, newlevel));
cudaTextureObject_t from_texture;
create_texture_object(from, true, &from_texture);
cudaSurfaceObject_t to_surface;
create_surface_object(to, &to_surface);
dim3 blocksize(16, 16, 1);
dim3 gridsize((width+blocksize.x-1)/blocksize.x,(height+blocksize.y-1)/blocksize.y, 1);
d_mipmap<<<gridsize, blocksize>>>(to_surface, from_texture, width, height);
checkCuda(cudaDeviceSynchronize());
checkCuda(cudaGetLastError());
uncreate_texture_object(&from_texture);
uncreate_surface_object(&to_surface);
Run Code Online (Sandbox Code Playgroud)
已知可以使用create_surface_object()代码。以防万一,这是create_texture_object()代码:
static void create_texture_object(cudaArray_t tarray, bool filter_linear, cudaTextureObject_t *tobject)
{
assert(tarray && tobject);
// build the resource
cudaResourceDesc color_res;
memset(&color_res, 0, sizeof(cudaResourceDesc));
color_res.resType = cudaResourceTypeArray;
color_res.res.array.array = tarray;
// the texture descriptor
cudaTextureDesc texdesc;
memset(&texdesc, 0, sizeof(cudaTextureDesc));
texdesc.addressMode[0] = cudaAddressModeClamp;
texdesc.addressMode[1] = cudaAddressModeClamp;
texdesc.addressMode[2] = cudaAddressModeClamp;
texdesc.filterMode = filter_linear ? cudaFilterModeLinear : cudaFilterModePoint;
texdesc.normalizedCoords = 1;
checkCuda(cudaCreateTextureObject(tobject, &color_res, &texdesc, NULL));
}
Run Code Online (Sandbox Code Playgroud)
d_mipmap设备功能如下:
__global__ void
d_mipmap(cudaSurfaceObject_t out, cudaTextureObject_t in, int w, int h)
{
float x = blockIdx.x * blockDim.x + threadIdx.x;
float y = blockIdx.y * blockDim.y + threadIdx.y;
float dx = 1.0/float(w);
float dy = 1.0/float(h);
if ((x < w) && (y < h))
{
#if 0
float4 color =
(tex2D<float4>(in, (x + .25f) * dx, (y + .25f) * dy)) +
(tex2D<float4>(in, (x + .75f) * dx, (y + .25f) * dy)) +
(tex2D<float4>(in, (x + .25f) * dx, (y + .75f) * dy)) +
(tex2D<float4>(in, (x + .75f) * dx, (y + .75f) * dy));
color /= 4.0f;
surf2Dwrite(color, mipOutput, x * sizeof(float4), y);
#endif
float4 color0 = tex2D<float4>(in, (x + .25f) * dx, (y + .25f) * dy);
surf2Dwrite(color0, out, x * sizeof(float4), y);
}
}
Run Code Online (Sandbox Code Playgroud)
其中包含mipmap采样代码(如果有的话)和调试代码。
问题是,color0始终统一为零,而我一直无法理解为什么。我已将过滤更改为点(从线性),但没有成功。我检查了错误。没有。
我在这里使用CUDA / OpenGL互操作,但是仅在CUDA阵列上完成了mipmap生成。
我真的真的不想使用纹理参考。
有什么建议在哪里看?
该错误原来是使用cudaMipmappedArrays(数组或纹理对象-我无法确定哪个损坏了。)
当我修改代码以仅使用cudaArrays时,纹理引用将再次开始工作。
由于无绑定纹理程序示例有效,因此该错误似乎仅限于float32通道mipmapped纹理。(我有一个测试程序,显示该错误同时发生在1通道和4通道float32 mipmapped纹理上。)
我已将该错误报告给Nvidia。
| 归档时间: |
|
| 查看次数: |
688 次 |
| 最近记录: |