2012-01-30 70 views
5

我正在使用CUDA Toolkit 4.0在我的Geforce 330M上嘗試OpenCL-OpenGL interop紋理。CL/GL-Interop錯誤的OpenGL紋理格式類型?

我想捕獲一個幀,將該數據用作輸入圖像(Image2D)到OpenCL內核。內核應該操作數據並將其寫入到一個Image2DGL,這是一個附帶OpenGL紋理的圖像對象。基本上,它看起來像這樣:

_______________  RGB  _______________ 
|    | uint8*  |    | CL_RGBA/CL_UNORM_INT8 
| Grabber  | ------------> | Image2D  | -------------------------. 
| avcodec  |    | [input]  |       | 
|_______________|    |_______________|       | 
                      |  
                      V 
_______________     _______________      _______________ 
|    |    |    |      |    | 
| Texture  | ------------> | Image2DGL | <-----------------> | Kernel  | 
|_______________|    | [output] |      |_______________| 
           |_______________| 
Internal 
Format: GL_RGBA 
Format: GL_RGBA 
Type: ? 

我初始化質地像:

GLuint tex = 0; 

void initTexture(int width, int height) 
{ 
    glGenTextures(1, &tex); 
    glBindTexture(GL_TEXTURE_RECTANGLE, tex); 
// now here is where I need assistance: The type parameter of the Texture (GL_FLOAT) 
    glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, NULL); 
} 


編輯:我能有一個類型的 GL_UNSIGNED_INT爲好。


然後,我創建共享圖像(Image2DGL):

texMems.push_back(Image2DGL(clw->context, CL_MEM_READ_WRITE, GL_TEXTURE_RECTANGLE, 0, tex, &err)); 

然後我創建源圖像(輸入圖像):

ImageFormat format; 
format.image_channel_data_type = CL_UNORM_INT8; 
format.image_channel_order = CL_RGBA; 
srcImgBuffer = Image2D(clw->context, CL_MEM_READ_WRITE, format, width, height, 0, NULL, &err); 

在每一個呈現循環我正在寫數據輸入到srcImgBuffer

// write the frame to the image buffer 
clw->queue.enqueueWriteImage(srcImgBuffer, CL_TRUE, origin, region, 0, 0, (void*)data, NULL, NULL); 

而且我設置的參數爲內核:我不獲取和釋放GL對象

​​

前後。測試內核看起來像這樣:

__kernel void init_texture_kernel(__write_only image2d_t out, __read_only image2d_t in, int w, int h) 
{ 
    const sampler_t smp = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST; 

    int2 coords = { get_global_id(0), get_global_id(1) }; 
    float4 pixel = read_imagef(in, smp, coords); 
    float4 test = { (float)coords.x/(float)w , 0, 0, 1}; 
    write_imagef(out, coords, pixel); 
} 

image_channel_data_type可以理解爲漂浮在內核和被解釋爲標準值。輸出圖像看起來不正確,我有一個切片圖片(線條),顯然是由於數據解釋錯誤。正如我所提到的,我認爲錯誤在紋理類型的初始化之內。我試過GL_FLOAT(因爲我正在寫內核中的圖像爲float)。

Results: Image as PPM dump from the decoder (left), Texture output scattered (right)

左邊一個是PPM出了解碼器的,正確的是什麼,我找回我的輸出質感。

如果有人真的讀到這裏:你有關於紋理類型的建議來解決這個問題嗎?


編輯:如果我直接綁定捕獲的幀到紋理,視頻播放OK。所以它必須以某種方式與CL-GL接口相關。


+0

Image2DGL是否返回錯誤?如果您使用常規2D紋理而不是矩形紋理,會發生什麼情況? – 2012-01-30 15:29:50

+0

不,從Image2DGL沒有錯誤。我之前嘗試過2D,對紋理座標進行了歸一化,並設置了Mag/Min濾鏡以及包裝,但是根本沒有輸出。 – rdoubleui 2012-01-30 15:40:54

回答

1

我終於想出瞭解決辦法,沒有看到明顯。我有一個RGB視頻。因此我在RGB中捕獲了幀。這可以很好地顯示在紋理上。但是,如果從緩衝區中立即獲取float4(如內核代碼所示),那麼只有三個通道存在,這當然會造成混亂。哎呀。

我也可以通過觀察行數來假設我的錯誤:我從512行請求的行中獲得了384條,這很好地達到了.75的比率。

我只是要求我的抓取器(使用libavcodec)抓住RGBA,它會爲我填充四通道圖片。

我會將此問題標記爲關閉。

2

我相信,如果你的最後一個參數glTexture2D爲NULL,然後格式化和類型的參數可以在任何有效的OpenGL格式/類型 - 但他們不使用,不影響任何東西。如果你想擁有浮點紋理,那麼你必須通過正確的internal_format參數指定:

glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, NULL); 
+0

我可以理解你的意思,但是我的源數據是uint8類型的,我正在尋找紋理的對應類型。我真的看不到任何8位數據類型。 – rdoubleui 2012-01-30 17:16:45

+0

如果我一開始沒有像初始化那樣初始化紋理,我看不到任何輸出,所以我認爲我需要它。然而,我可以擁有'GL_RGBA8'或'GL_RGBA32F',這似乎沒有什麼區別。我不明白。 – rdoubleui 2012-01-30 17:26:03

+0

glTexImage2D的第7個和第8個參數指定數據在最後一個參數中傳遞的格式和類型。如果您沒有將任何數據傳遞給glTexImage2D,那麼這兩個參數中的值不會影響任何內容。 – 2012-01-30 18:28:18