2012-01-30 12 views
5

Sto provando l'interoperabilità OpenCL-OpenGL per trame sul mio Geforce 330M con CUDA Toolkit 4.0.Tipo di formato trama OpenGL errato per CL/GL-Interop?

Desidero acquisire un frame, utilizzare quei dati come immagine di input (Image2D) su un kernel OpenCL. Il kernel dovrebbe manipolare i dati e scriverli su un Image2DGL, che è un oggetto immagine con una trama OpenGL allegata. In pratica sembra che:

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

che sto inizializzare la trama del genere:

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); 
} 


EDIT: posso avere un tipo di GL_UNSIGNED_INT pure.


Poi creo l'immagine condivisa (Image2DGL):

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

Poi ho creare il (immagine in ingresso) immagine d'origine:

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); 

In ogni render ciclo che sto scrivendo i dati nel srcImgBuffer:

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

Anche io sto impostando gli argomenti per il kernel:

tex_kernel.setArg(0, texMems[0]); 
tex_kernel.setArg(1, srcImgBuffer); 
tex_kernel.setArg(2, width); 
tex_kernel.setArg(3, height); 

Prima e dopo io acquisire e rilasciare gli oggetti GL. Il kernel test sembra che:

__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); 
} 

il image_channel_data_type può essere letta come float nel kernel e viene interpretato come valore normalizzato. L'immagine di output non sembra corretta, ho un'immagine a fette (in linewise), ovviamente a causa dell'interpretazione errata dei dati. Come ho detto, suppongo che l'errore sia all'interno dell'inizializzazione del tipo di trama. Ho provato GL_FLOAT (mentre sto scrivendo come float per l'immagine nel kernel).

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

Quello di sinistra è un PPM fuori dal decoder, quello di destra è quello che sto ricevendo indietro sulla mia uscita texture.

Se qualcuno legge fino a qui: hai suggerimenti sul tipo di trama per risolvere il problema?


EDIT: Se mi legano i frame acquisiti alla texture direttamente, il video viene riprodotto ok. Quindi deve essere correlato all'interfaccia CL-GL in qualche modo.


+0

Image2DGL ha restituito un errore? E cosa succede se usi una trama 2D normale anziché una trama rettangolare? –

+0

No, nessun errore da Image2DGL. Ho provato prima il 2D, ho normalizzato le texture coord e ho impostato il filtro Mag/Min e il wrap, ma non ho avuto alcun risultato. – rdoubleui

risposta

1

alla fine ho si avvicinò con la soluzione, non vedere l'ovvio. Ho avuto un video RGB. Ho quindi catturato i fotogrammi in RGB. Questo può essere visualizzato su una texture bene. TUTTAVIA, se si prende uno float4 dal buffer in una volta (come si vede nel codice del kernel) dove sono presenti solo tre canali, questo andrà a rovinare tutto, ovviamente. Argh.

Avrei anche potuto presumere il mio errore guardando il conteggio delle righe: ho ottenuto 384 linee su 512 righe richieste, il cui valore è pari a .75.

Ho semplicemente richiesto al mio grabber (utilizzando libavcodec) di afferrare RGBA e lo avrebbe riempito per avere un'immagine a quattro canali.

Contrassegnerò questa domanda da chiudere.

2

Credo che se il vostro ultimo argomento glTexture2D è NULL, quindi formattare e argomenti di tipo può in qualsiasi formato OpenGL/tipo valido - ma non vengono utilizzate e non influenza nulla.Se si desidera avere consistenza punto fluttuante, allora è necessario specificarlo passando argomento internal_format corretto:

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

Posso capire cosa intendi, tuttavia i miei dati sorgente sono di tipo uint8 e sto cercando un tipo corrispondente per la texture. Non riesco davvero a vedere alcun tipo di dati a 8 bit. – rdoubleui

+0

Se non riesco a inizializzare la texture in quel modo all'inizio, non riesco a vedere alcun output, quindi prendo quello di cui ho bisogno. Posso comunque avere 'GL_RGBA8' o' GL_RGBA32F', non sembra fare la differenza. Non lo capisco – rdoubleui

+0

Il settimo e l'ottavo argomento per glTexImage2D specifica in quale formato e tipo i dati vengono passati nell'ultimo argomento. Se non si trasmettono dati a glTexImage2D, i valori in questi due argomenti non influiscono su nulla. –

Problemi correlati