【问题标题】:Write to GL_ARRAY_TEXTURE_2D OpenGL interop fails写入 GL_ARRAY_TEXTURE_2D OpenGL 互操作失败
【发布时间】:2016-02-10 02:15:58
【问题描述】:

我需要使用 CUDA 图形互操作功能写信给OpenGL GL_ARRAY_TEXTURE_2D。我使用 CUDA 驱动程序 API,CUDA 版本 7.5。我的 GPU 是带有 CC3.0 的 NVIDIA Quadro K4000 我创建这样的 OpenGL 阵列纹理(5 层):

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &_glArrayTexHandle);
glBindTexture(GL_TEXTURE_2D_ARRAY, _glArrayTexHandle);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP);

glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA32F, m_viewportWidth, m_viewportHeight, 5, 0, GL_RGBA, GL_FLOAT, 0);
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);

然后在 CUDA 方面,我为要与 CUDA 表面一起使用的纹理创建图形图像资源:

checkCudaErrors(cuGraphicsGLRegisterImage(&m_cudaToGL_TEX_ARRAY_Resource, _glArrayTexHandle, GL_TEXTURE_2D_ARRAY, CU_GRAPHICS_REGISTER_FLAGS_SURFACE_LDST));
assert(m_cudaToGL_TEX_ARRAY_Resource);

checkCudaErrors(cuModuleGetSurfRef(&m_surfGLtexRef, m_module, "surfaceWrite"));
assert(m_surfGLtexRef);

在渲染循环期间,我正在映射资源并在数组指针和要写入内核的表面之间设置引用:

   checkCudaErrors(cuGraphicsMapResources(1, &m_cudaToGL_TEX_ARRAY_Resource, 0));
   //write to layer number 3
   checkCudaErrors(cuGraphicsSubResourceGetMappedArray(
   &m_cudaOffscreenFBOTextureArrayPtr, m_cudaToGL_TEX_ARRAY_Resource, 3, 0));
    assert(m_cudaOffscreenFBOTextureArrayPtr);

    checkCudaErrors(cuSurfRefSetArray(m_surfGLtexRef, m_cudaOffscreenFBOTextureArrayPtr, 0));



   ///launch the kernel:

    checkCudaErrors(cuLaunchKernel(function,
        blockDimX,
        blockDimY,
        1,
        block_size,
        block_size,
        1,
        0,
        NULL,
        args,
        NULL
        ));

    checkCudaErrors(cuGraphicsUnmapResources(1, &m_cudaToGL_TEX_ARRAY_Resource, 0));
    checkCudaErrors(cuCtxSynchronize());

内核看起来像这样:

surface<void, cudaSurfaceType2DLayered> surfaceWrite;
extern "C" __global__ void surfWriteFunc(int xOffset, int yOffset, int Width, int Height)

{

    unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
    unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;

    if (x >= Width || y >= Height)
    {
     return;
    }

    float4 dataOut =  make_float4(1.0f, 0.0f, 1.0f, 1.0f);

    surf2DLayeredwrite(dataOut, surfaceWrite, x * sizeof(float4), y, 3);

 }

我正在尝试使用 CUDA layered surface 写入。至少我认为这应该与 GL_ARRAY_TEXTURE_2D 一起使用。否则 NVIDIA 文档对如何执行此操作的信息为零。我得到的错误是

CUDA_ERROR_LAUNCH_FAILED 用于渲染过程中调用的每个 cuda 方法,如上所示。我尝试过,例如使用 cudaSurfaceType3D 而不是分层,但它没有帮助。如果有人能摆脱它会很好GL 阵列纹理与 CUDA 互操作的一些亮点。

【问题讨论】:

  • 如果没有重现案例,我真的很难理解有人如何告诉你出了什么问题。 CUDA API 调用可能会从之前的调用中返回失败,因此除非您提供完整的示例或准确指出失败的开始位置,否则无法诊断问题。如果你运行 cuda-memcheck 会发生什么?例如,您是否从内核中得到了更具建设性的错误?
  • 我的问题很清楚。错误来自内核启动的那一刻。我没有包含的额外代码是OpenGL和CUDA上下文初始化+一些渲染逻辑。但是我的问题更多的是关于“CUDA是否以及如何支持使用OpenGL进行分层互操作写入”但没关系,我想我已经解决了这个问题。SO变成了一个令人讨厌的提问地方。人们当场投票只是因为他们不理解问题。
  • 如果您对此问题有解决方案,能否将其添加为答案。至于投票,我承认——我投票结束了这个。我这样做是因为真的不清楚你想要什么样的答案。一方面,您有一个内核出现故障并破坏了您的 CUDA 上下文。如果您想确切地知道是什么原因造成的,您需要提供一个重现案例或更精确的信息,而您没有。另一方面,唯一的问题似乎是“。如果有人能对 GL 阵列纹理与 CUDA 互操作有所了解,那会很好吗?”这是相当广泛的
  • 这根本不宽泛。有能力(至少是 CUDA 纯文档状态)映射到 GL_ARAY_TEXTURE_2D。问题是如何?这是一个非常狭窄的问题。没有很多方法可以做那个。事实上,只有一个。现在,在我看来,有些人在所讨论的领域甚至不具备最低限度的专业知识时都在试图争论。

标签: opengl cuda


【解决方案1】:

经过多次试验和错误,我发现它是如何工作的。首先,当涉及到映射到 GL 资源的 CUDA 数组指针时,CUDA 似乎不允许分层表面写入。所以内核中的这段代码

surf2DLayeredwrite(dataOut, surfaceWrite, x * sizeof(float4), y, 3);

无效,因为只能访问映射数组的第 0 层。 有效代码是

 surf2DLayeredwrite(dataOut, surfaceWrite, x * sizeof(float4), y, 0);

因此根本没有理由使用 surf2DLayeredwrite,只是平常使用

2D 表面写入:

  surf2Dwrite(dataOut, surfaceWrite, x * sizeof(float4), y);

现在回答问题“如何写入 GL_ARRAY_TEXTURE_2D 的不同层?

 checkCudaErrors(cuGraphicsSubResourceGetMappedArray(
&m_cudaOffscreenFBOTextureArrayPtr, m_cudaToGL_TEX_ARRAY_Resource, **3**, 0));

其中“3”是映射数组纹理中要写入的层的索引。 我还没有找到从内核中选择层索引的方法。目前看来只能在主机上进行。

【讨论】:

    【解决方案2】:

    这个答案来晚了,但也许它可以帮助某人......

    我没有尝试过 GL_ARRAY_TEXTURE_2D,但我可以说至少 GL_TEXTURE_3D 纹理索引将在 CUDA 内核中动态工作(从 compute_20、sm_21 和 CUDA 5.0 开始,可能还有 CUDA 4.1 和 CUDA 4.2)。

    但是,对于三维纹理,您需要了解一个问题:您必须在发布模式下编译您的 CUDA 程序,而不是在调试模式下。

    【讨论】:

    • 哦,真的吗?在发布中?你确定这不是错误吗?
    • 当然,这就是使用 GL_TEXTURE_3D 和 C++ Visual Studio 10 拯救我的方法。一个错误?好吧,我认为 CUDA 有很多错误......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 2011-09-22
    • 2019-07-15
    • 2023-04-10
    • 2020-09-14
    • 2020-03-25
    • 1970-01-01
    相关资源
    最近更新 更多