2013-05-06 83 views
3

我正在進行3D模擬(現在是2D),我正在使用CUDA進行計算,OpenGL進行渲染。我的問題涉及CUDA和OpenGL之間的互操作性。 據我所見,有兩種一般的方法可以做到這一點:CUDA和OpenGL互操作類型

第一個將使用映射到CUDA全局內存然後複製到其中的像素緩衝區對象(或頂點緩衝區對象)一個OpenGL紋理。據說這是一種非常快速的方法。

第二個是將紋理對象直接複製到CUDA紋理內存。這也將是非常好的,因爲我可以使用紋理內存的所有功能,如紋理緩存等。

現在,有人可以向我解釋這兩種方法之間的一般差異是什麼?而且他們每個人通常使用什麼樣的情況?

回答

4

整個區別就像你說的,在紋理緩存中。因此,在這些方法之間進行選擇取決於您是否要在可視化中利用紋理緩存。讓我們來看一些常見的情況:

a)如果你想要計算一個曲面如何變形(例如水面或者一些彈性變形),你需要知道曲面的多邊形網格的新頂點那麼你通常會使用緩衝區(第一),除非你不需要在這裏複製到OpenGL紋理。事實上,這裏不涉及複製,你只需在CUDA中引用緩衝區並將其用作gl緩衝區。 b)如果你有一個粒子模擬,並且需要知道更新粒子的位置,那麼你也可以像上述情況那樣使用一個緩衝區。 c)如果你有一個有限元網格模擬,其中空間中的每個固定體積的單元格將獲得一個新的值,並且你需要通過體繪製或等值面對其進行可視化,在這裏你會想使用一個紋理對象(2D或3D,這取決於你的模擬的維度),因爲當你投射光線,或者甚至產生流線時,你幾乎總是需要立即使相鄰紋理元素緩存。你可以避免在這裏進行任何複製,就像上面的方法一樣,你也可以直接從OpenGL引用一些CUDA紋理內存(cudaArray)。你可以使用這些調用來做到這一點:

cudaGraphicsGLRegisterImage(&myCudaGraphicsResource, textureNameFromGL, GL_TEXTURE_3D,...) 
... 
cudaGraphicsMapResources(1, myCudaGraphicsResource) 
cudaGraphicsSubResourceGetMappedArray(&mycudaArray, myCudaGraphicsResource, 0, 0) 
cudaGraphicsUnMapResources(1, myCudaGraphicsResource) 

所以這個質地CUDA數據可以通過mycudaArray引用而在OpenGL這個相同的內存可以通過textureNameFromGL引用。

從緩衝區複製到紋理中是一個壞主意,因爲如果您需要此數據進行紋理緩存,您將執行額外的複製。在紋理互操作被支持之前,這在早期版本的CUDA中更受歡迎

您也可以在a)和b)用例中使用紋理。有些硬件甚至可能運行得更快,但這是非常依賴硬件的。請記住,紋理閱讀也適用縮小和放大過濾器,這是額外的工作,如果你正在尋找的是一個存儲在緩衝區中的確切值。

對於CUDA和OpenGL請參閱本樣本

https://github.com/nvpro-samples/gl_cuda_interop_pingpong_st

共享紋理資源