2015-11-09 148 views
-2

我需要使用CUDA圖形互操作功能編寫OpenGL GL_ARRAY_TEXTURE_2D。我使用CUDA Driver API,CUDA版本7.5。我的GPU是NVIDIA Quadro K4000,帶有CC3.0我創建OpenGL陣列紋理,如下所示層):寫入GL_ARRAY_TEXTURE_2D OpenGL互操作失敗

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側I創建圖形圖像的資源用於該紋理與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); 

在renderloop我映射所述陣列之間的資源和設置的參考指針和要寫入的曲面在內核:

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 write.At至少這就是我想應該GL_ARRAY_TEXTURE_2D。否則NVIDIA的文檔都可以使用關於如何做後援的錯誤我得到零信息是

CUDA_ERROR_LAUNCH_FAILED爲每個渲染過程中調用CUDA方法,看到above.I嘗試,例如使用cudaSurfaceType 3D,而不是分層,但它沒有幫助。如果有人能夠在GL與CUDA交互的紋理上進行一些闡述,那可能會很好。

+1

如果沒有repro case,我真的很難理解someoine怎麼能告訴你什麼是錯的。CUDA API調用可以返回早期調用的失敗,因此除非您提供了完整的示例或精確定位了失敗開始的位置,否則無法診斷問題。如果你運行cuda-memcheck會發生什麼?例如,您是否從內核獲得了更具建設性的錯誤? – talonmies

+0

我的問題很清楚。錯誤來自內核啓動的時刻。我沒有包含的額外代碼是OpenGL和CUDA上下文init +一些渲染邏輯。但我的問題更多地是關於「if和CUDA如何支持使用OpenGL進行分層互操作編寫「但是沒關係,我想我已經找到了問題所在.So成爲一個討厭問題的地方。人們只是因爲沒有理解這個問題而在現場下了功夫。 –

+0

如果你有解決這個問題的方法,你可以把它添加爲答案。至於投票,我自己決定 - 我投票結束了這個。我這樣做是因爲它真的不清楚你想要什麼樣的答案。一方面你會看到一個內核失敗並破壞你的CUDA上下文。如果你想知道究竟是什麼造成的,你需要提供一個repro case或更精確的信息,而你卻沒有。另一方面,唯一的問題似乎是「。如果任何人都可以通過與CUDA交互的GL陣列紋理了解一些情況,這可能會很好嗎?」這是非常廣泛的 – talonmies

回答

1

多次試驗後&錯誤,我發現它是如何works.First,好像CUDA不允許分層表面寫入,當談到這個代碼映射到GL resource.So內核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」是要寫入的映射陣列紋理中圖層的索引。 我還沒有找到從內核中選擇圖層索引的方法。目前看來只能在主機上執行。

0

這ansver來得晚,但也許它可以幫助別人......

我沒有試過GL_ARRAY_TEXTURE_2D,但我可以說,至少GL_TEXTURE_3D紋理元素的索引將動態工作CUDA內核內部(從compute_20開始, sm_21和CUDA 5.0,可能還有CUDA 4.1和CUDA 4.2)。

但是,您需要了解三個維度紋理的一個問題:您必須在發佈模式下編譯CUDA程序,而不是在調試模式下編譯。

+0

哦,真的嗎?在發佈中?你確定這不是一個bug嗎? –

+0

當然,這是用GL_TEXTURE_3D和C++ Visual Studio 10救了我的方式。一個bug?好吧,我認爲CUDA有很多缺陷...... – mamannon